目標
開発環境
・Ruby 2.3.1
・Rails 5.1.3
使用したモデル
userモデル(誰がいいねするか)
closetモデル(どの服にいいねするか)
likeモデル(いいね自身)
likesテーブル作成
userモデルやclosetモデル、closetsコントローラーは作成済みで進めていきます。
まずはターミナルでlikeモデルを作成します。その後migrationファイルを以下のように編集しましょう。
class CreateLikes < ActiveRecord::Migration[5.1]
def change
create_table :likes do |t|
t.references :closet, foreign_key: true
t.references :user, foreign_key: true
t.timestamps
end
end
end
アソシエーションを定義する
class Like < ApplicationRecord
belongs_to :closet
belongs_to :user
end
class Closet < ApplicationRecord
has_many :likes, dependent: :destroy
def like_user(id)
likes.find_by(user_id: id)
end
end
closetが削除されたらそれに紐づくlikeも削除したいのでオプションでdependent: :destroyを記述します。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
#いいね機能のアソシエーション
has_many :likes, dependent: :destroy
end
こちらも先ほど同様にオプションでdependent: :destroyを記述します。
likesコントローラー作成
class LikesController < ApplicationController
before_action :set_closet, only: [:create, :destroy]
def create
@like = current_user.likes.create(closet_id: params[:closet_id])
@closets = Closet.all
end
def destroy
like = current_user.likes.find_by(closet_id: params[:closet_id])
like.destroy
@closets = Closet.all
end
private
def set_closet
@closet = Closet.find(params[:closet_id])
end
end
closetsコントローラーのアクション定義
class ClosetsController < ApplicationController
def index
@closets = Closet.all
end
end
ルーティング追加
Rails.application.routes.draw do
resources :closets do
resources :likes, only: [:create, :destroy]
end
end
view作成
今回はslimでviewを記述しています。
#js-grid-juicy-projects
/@closetsをrender先でそれぞれを取り出してclosetとして渡す
= render @closets
/画像用なので記述しなくてよい
.cbp-caption-defaultWrap
= image_tag closet.thumbnails.first.image, class: "item-thumbnail-capture item-thumbnail-size"
/ここから必要
.like-link
= render partial: 'likes/like_links', locals:{ closet: closet }
※画像とかじゃなく他の何かにいいねする場合は.like-linkのcssになにかしらの記述いると思います。
いいねボタンを部分テンプレートで渡すのでlikesフォルダをviewsの中に作ります
- if closet.like_user(current_user.id)
= link_to closet_like_path(closet, closet.like_user(current_user)), method: :delete, class: 'heart-icon', remote: true do
.fa.fa-heart.fa-2x.heart-red
- else
= link_to closet_likes_path(closet), method: :post, class: 'empty-heart', remote: true do
.fa.fa-heart-o.fa-2x.heart-color
ハートマークはgemのfont-awesome-railsを使用して表示させています。
いいねしてるかどうかで条件分岐させ,closet.like_userのlike_userはclosetモデルに記述したメソッドを使ってます。
= link_to closet_like_path(closet, closet.like_user(current_user))の引数なのですが、
第一引数のclosetはclosetsコントローラーからとってこれたのですが、第二引数がコントローラーから持ってくる方法がわからず、モデルに記述したメソッドを使用しました。他にいい方法があれば教えて欲しいです。
ちなみにrake routeした結果がこちらです。
#jsファイル作成
$("#js-grid-juicy-projects").html("<%= j(render @closets) %>");
$("#js-grid-juicy-projects").html("<%= j(render @closets) %>");
jsファイルはこれだけです。
以上で完成となります。
参考サイト