If you find a product that you think is good for online shopping, have you registered it as a favorite? At that time, if the screen is not updated and you like it or like it, the color of the ♡ mark will change. After that, it would be nice if you could check your favorite products in a list. This time is a memo of the implementation.
When you click on the completed image, a part of the screen is updated and the number count increases. It also has a delete function. We will also create a page where you can check what you have added to your favorites in a list.
First, as an intermediate table between the items table and the users table Create a likes table.
↓ The columns to be added and the association look like this ↓
Column | Type | Options |
---|
=== Abbreviation ===
Column | Type | Options |
---|---|---|
item_id | integer | null: false |
user_id | integer | null: false |
Association
Column | Type | Options |
---|
=== Abbreviation ===
Association
This completes the DB design Next, create a model. Enter the following command in the terminal
rails g model like
Edit migration file to create table
2XXXXXXXXXXXX5_create_likes.rb
class CreateLikes < ActiveRecord::Migration[5.2]
def change
create_table :likes do |t|
t.integer :item_id, null: false
t.integer :user_id, null: false
end
end
end
Rails from db: migrate. Then a model will be generated, so we will write the association.
user.rb
has_many :likes #add to
item.ruby
has_many :likes #add to
like.rb
class Like < ApplicationRecord
belongs_to :item
belongs_to :user
validates :user_id, presence: true
validates :item_id, presence: true
validates_uniqueness_of :item_id, scope: :user_id
def self.like_method(item, user)
Like.find_by(item_id: item.id, user_id: user.id)
end
end
self.like_method(item, user) I will set the IF statement here. Set the condition that item_id and user_id are in the like table! Then run the following command to create the controller
rails g controller likes
Once the controller is created successfully ・ View file ·controller ·routing I will set each.
routes.rb
--Omitted ---
resources :items, only: [:new, :create, :edit, :update, :show, :destroy] do
resources :likes, only: [:create, :destroy]
end
--Omitted ---
resources :users, only: [:show] do
resources :likes, only: [:index]
end
--Omitted ---
create and destroy are nested in items index nested in users
likes_controller.rb
class LikesController < ApplicationController
before_action :set_item, only: [:create, :destroy]
def index
@items = Item.includes(:item_images).order("created_at DESC")
end
def create
@like = Like.create(item_id: params[:item_id],user_id: current_user.id)
redirect_to item_path(@item.id)
end
def destroy
@like = Like.find_by(item_id: params[:item_id],user_id: current_user.id)
@like.destroy
redirect_to item_path(@item.id)
end
def set_item
@item = Item.find(params[:item_id])
end
end
Since create and destroy do not have a view file, you need to set redirects.
index.html.haml
--Omitted ---
- if user_signed_in? && Like.like_method(@item, current_user)
.check_btn__like--add{data: {item_id: @item.id}}
= link_to "/items/#{@item.id}/likes/:id" , method: :DELETE do
= icon( "fa", "star")
favorite
= @item.likes.length
- elsif user_signed_in?
.check_btn__like{data: {item_id: @item.id}}
= link_to "/items/#{@item.id}/likes", method: :POST do
= icon( "fa", "star")
favorite
= @item.likes.length
- else
.check_btn__like
= link_to new_user_session_path do
= icon( "fa", "star")
favorite
= @item.likes.length
--Omitted ---
Click here for the screen when registering as a favorite
index.html.haml
.mypage_Wrapper
%section.mypage_title
Favorite list
%section.like_Wrapper
.like__box
- @items.each do |item|
- if user_signed_in? && Like.like_method(item, current_user)
.like__box__product
.like__image
= link_to item_path(item.id) do
= image_tag item.item_images[0].image.url
.like__name
= item.name
%ul
%li
= item.price.to_s
%li
= "Circle"
%li.like__tax
= "(tax included)"
%li.like__icon
= link_to "/items/#{item.id}/likes/:id" , method: :DELETE do
= icon("fas", "star")
.bottom_Wrapper
This is what you see in your favorite product list
like.scss
.like_Wrapper {
width: 100%;
}
.like__box {
background-color:white;
margin: 0 auto;
width: 65%;
display: flex;
justify-content: center;
flex-wrap: wrap;
&__product {
width: 180px;
height: 90%;
margin: 25px 2% 0;
transition: all .3s ease-in-out;
.like__image {
width: 180px;
height: 140px;
margin-bottom: 3%;
img{
width: 100%;
height: 100%;
object-fit: cover;
}
}
.like__name {
font-weight: bold;
}
ul{
display: flex;
font-size: 16px;
li{
font-weight: bold;
}
.like__tax {
font-size: 10px;
writing-mode: lr-tb;
width: 30px;
line-height: 30px;
margin-left: 2%;
margin-right: 24%;
}
.like__icon {
i {
font-size:1.1em;
color: orange;
}
}
}
}
&__product:hover {
cursor: pointer;
transform: scale(1.1, 1.1);
}
}
For the time being, CSS I think that it can be implemented in a synchronized state with the implementation so far! So far, if you implement asynchronous communication using Ajax, it will be richer, so I wish I could write that ... It will be later ...
https://techtechmedia.com/favorite-function-rails/#i https://qiita.com/naberina/items/c6b5c8d7756cb882fb20 https://qiita.com/hisamura333/items/e3ea6ae549eb09b7efb9 https://qiita.com/shh-nkmr/items/48fe53282253d682ecb0
Recommended Posts