I made a portfolio with Ruby On Rails

■ Introduction

I created a simple app with Ruby on Rails, so I had a hard time I wrote an article because I wanted to make a note of the points I devised as a memorandum in the future.

■ Environment construction

・ Mac ・ Git installed ・ Ruby 2.6.5 ・ Rails 6.0.3.4 ・ Visual Studio Code

■ Overview of the app

It is an application that allows users to share clothes. When I usually buy clothes, I often refer to the clothes worn by others, so it would be convenient to have an app that allows me to share photos of the clothes I have, impressions of coming, and prices. I thought, I created it.

■ Database design

The following three tables are used this time. A user can post multiple clothes (fuku). In addition, the intermediate table allows users to like the posted clothes.

users table

column type
id string
name string
email string
profile_image_id string

fukus table

column type
id string
title string
body text
user_id integer
image_id string

likes table (intermediate table)

column type
id string
user_id integer
fuku_id integer

devise implementation

When creating the login authentication function, it takes time to create everything from scratch, so I used devise, which is easy to implement.

$rails generate devise :install

The setting method required for the login function will appear, so add the code. In addition, create a User model based on devise.

$rails g devise User

At this time, the User model based on devise has only email and password columns by default, so add name and profile_image_id to the migration file.

$rails g migration add_name_to_users name:string profile_image_id:string
$rails db:migrate

Add the profile_image and name fields to the new registration view as well.

ruby:new.html.erb


<div class="field">
  <%= f.label :profile image%>
  <%= f.attachment_field :profile_image %>  
</div>

<div class="field">
  <%= f.text_field :name, autofocus: true, placeholder:"name", autocomplete: "name"%>
</div>

I thought that the user's new registration function could be implemented with this, but even if I set the name and profile image on the new registration screen It was not reflected in the database. Upon investigation, it was found that devise only accepts email addresses and passwords when registering new by default. By describing the strong parameter in application.controller as shown below, the added column can also be received.

ruby:application.controller.rb


def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :profile_image])
end

Implementation of Refile

I want to implement the function to post images to each of the user model and Fuku model, so I decided to use refile. There is a carrierwave in another similar gem, but refile is a relatively new one created by the creator of carrierwave as a successor, so I used refile this time. I referred to this article on Qiita. https://qiita.com/salvage0707/items/2614c97a1f256027ef71

Intermediate table

We will implement a function that allows you to like the posted clothes.

Required processing

(1) "Like user id: user_id" and "Like clothes id: fuku_id" are saved in "Intermediate table: likes table". ② The like button switches depending on "Like" and "Like completed".

Like model

First, create a table (likes table) that stores "liked users" and "liked clothes".

$rails g model like user_id:integer fuku_id:integer
$rails db:migrate

Association

We will describe the association for the model. User and Fuku are one-to-many, User and Like are one-to-many, Fuku and Like are also one-to-many, so

user.rb


has_many :fukus
has_many :likes

fuku.rb


belongs_to :user
has_many :fukus

like.rb


belongs_to :user
belongs_to :fuku

It will be.

routing

Likes are nested inside fukus to like the posted clothes. I felt that resource is very convenient because routing is automatically trained just by writing one line.

 resources :fukus do
      resources :likes, only:[:create, :destroy]
 end

controller

Make a likes controller.

$rails g controller likes

Then on the clothing details page, edit the view so that the logged-in user can like it. Make sure that the logged-in user behaves differently when they already like it and when they don't.

ruby:app/views/fukus/show.html.erb


<% if Like.find_by(user_id:current_user.id, fuku_id:@fuku.id) %>
 <p><%= link_to 'Liked', fuku_likes_path(@fuku), method: :delete %></p>
<%else%>
 <p><%= link_to 'How nice', fuku_likes_path(@fuku), method: :post %></p>
<%end%>

Describe the likes controller as follows, and store the id of the user who liked and the post in the likes table of the user who is logged in with the create action. The destroy action is used to cancel the like.

likes_controller.rb


def create
 @like=Like.new(user_id:current_user.id, fuku_id:params[:fuku_id])
 @lika 
 redirect_back(fallback_location: root_path)
end

def destroy
 @like =Like.find_by(user_id:current_user.id, fuku_id:params[:fuku_id])
 @like.destroy
 redirect_back(fallback_location: root_path)
end

Then edit the controller and view so that you can see the likes on the user detail page.

@ fukus → Get user_id of clothes posted by each user @ likes → Get the user_id of the likes pressed by each user

users_controller.rb


def show
    @user=User.find_by(id:params[:id])
    @fukus=Fuku.where(user_id:@user.id)
    @likes=Like.where(user_id:@user.id)
end

ruby:app/users/show.html.erb


  <% @likes.each do |like| %>
         <% fuku=Fuku.find_by(id:like.fuku_id)%>
         <%= link_to(fuku_path(fuku)) do %>
          <%=attachment_image_tag fuku,:image,class:"thumbnail150" %>
         <%end%>
  <%end%>

This completes the implementation of the like function.

Supplement

before_action :authenticate_user! By writing at the beginning of the controller, the processing performed there can be executed only by the logged-in user. Also, for example, if you want to allow users who are not logged in to perform only the index action, describe as follows.

class FukusController < ApplicationController
  before_action :authenticate_user!, except: [:index]
  
 def index
    @fukus=Fuku.all
  end

  def show
    @fuku=Fuku.find_by(id:params[:id])
  end
end

What I want to learn in the future

By creating the app from scratch, I think I have acquired the minimum knowledge of CRUD processing. I still get errors frequently, but I think that by referring to similar articles, I have gained the ability to investigate and solve them myself. I would like to continue learning more and add, for example, a function that allows users to send messages to each other, and a function that allows users to search by clothing brand, type, and price range. Also, I'm not good at implementing the front end, so I'd like to study that area as well.

Recommended Posts

I made a portfolio with Ruby On Rails
I made a risky die with Ruby
I want to add a browsing function with ruby on rails
Publish the app made with ruby on rails
I made a LINE bot with Rails + heroku
[Ruby] I made a crawler with anemone and nokogiri.
Ruby: I made a FizzBuzz program!
I made a GUI with Swing
I tried installing Ruby on Rails related plugin with vim-plug
I made a development environment with rails6 + docker + postgreSQL + Materialize.
[Ruby on Rails] Add a column with a foreign key constraint
[Ruby on Rails] View test with RSpec
[Ruby] I made a simple Ping client
Notes on using FCM with Ruby on Rails
[Ruby on Rails] Controller test with RSpec
I made a rock-paper-scissors app with kotlin
I made a calculator app on Android
[Portfolio] Bookmark management app [Ruby on Rails]
[Ruby on Rails] Model test with RSpec
Beginners create portfolio in Ruby on Rails
I made a rock-paper-scissors app with android
Steps to build a Ruby on Rails development environment with Vagrant
Introducing Rspec with Ruby on Rails x Docker
04. I made a front end with SpringBoot + Thymeleaf
I made an app to scribble with PencilKit on a PDF file
I made a gender selection column with enum
[Ruby on Rails] Create a pie chart for each column with Chartkick
I made blackjack with Ruby (I tried using minitest)
I made a Ruby extension library in C
[Rails] I made a draft function using enum
Introducing Rspec, a Ruby on Rails test framework
[Ruby on Rails] A memorandum of layout templates
Ruby on Rails basics
Incorporate Docker into your Ruby on Rails portfolio!
How to build a Ruby on Rails development environment with Docker (Rails 6.x)
(Ruby on Rails6) Creating data in a table
Ruby On Rails Association
Determine the current page with Ruby on Rails
How to build a Ruby on Rails development environment with Docker (Rails 5.x)
[Ruby on Rails] Upload multiple images with refile
I made a site that summarizes information on carbohydrate restriction with Vue.js
I understand Ruby on Rails params (with Hanshin Tigers poker faceman, Atsushi Nomi)
Build a Ruby on Rails development environment on AWS Cloud9
Run Ruby on Rails RSpec tests with GitHub Actions
I made a drawing chat "8bit paint chat" on WebAssembly
Solve the N + 1 problem with Ruby on Rails: acts-as-taggable-on
[Beginner] I stumbled upon launching a project with Rails6
I made a library for displaying tutorials on Android.
Created RSS / Atom format sitemap with Ruby on Rails
Ruby on rails learning record -2020.10.03
I tried DI with Ruby
Ruby on rails learning record -2020.10.04
[Ruby on Rails] Debug (binding.pry)
Ruby on rails learning record -2020.10.05
Ruby on rails learning record -2020.10.09
Ruby on Rails config configuration
Ruby on Rails basic learning ①
I made a chat app.
[Ruby on Rails] about has_secure_password
Ruby on rails learning record-2020.10.07 ②
Commentary on partial! --Ruby on Rails