$bin/rails g model like
class CreateLikes < ActiveRecord::Migration[5.2]
def change
create_table :likes do |t|
t.references :user, null: false
t.references :post, null: false
t.timestamps
end
add_index :likes, [:user_id, :post_id], unique: :true
end
end
https://310nae.com/rails-uniqueness/
class Like < ApplicationRecord
belongs_to :user
belongs_to :post
validates_uniqueness_of :post_id, scope: :user_id
end
続いて、post.rbを「1対多」、user.rbを「多対多」にアソシエーションさせる
class Post < ApplicationRecord
belongs_to :user
has_many :likes, dependent: :destroy
validates :title, presence: true, length: { maximum: 255 }
validates :content, presence: true, length: { maximum: 65_535 }
def liked_by?(user)
likes.where(user_id: user).exists?
end
end
class User < ApplicationRecord
authenticates_with_sorcery!
has_many :posts, dependent: :destroy
has_many :likes, dependent: :destroy
has_many :likes_posts, through: :likes, source: :post
validates :password, length: { minimum: 3 }, if: -> { new_record? || changes[:crypted_password] }
validates :password, confirmation: true, if: -> { new_record? || changes[:crypted_password] }
validates :password_confirmation, presence: true, if: -> { new_record? || changes[:crypted_password] }
validates :email, uniqueness: true
validates :email, presence: true
validates :first_name, presence: true, length: { maximum: 255 }
validates :last_name, presence: true, length: { maximum: 255 }
def mine?(object)
# 呼び出し元のオブジェクトのIDを示す self.id を省略した記法。
# @user.mine?(object)のように利用すると、object.user_id と @user.id を比較する。
object.user_id == id
end
def like(post)
likes_posts << post
end
def unlike(post)
likes_posts.delete(post)
end
def like?(post)
likes_posts.include?(post)
end
end