初めてユニークネスを使ったのでメモ
uniqueness
必ず一意であること。 など、同じ情報を保存しないようにする 例)メールアドレスや電話番号など今回使った状況としては、Userは投稿を追加することができ、さらにその中で投稿に紐づく商品の情報を追加することができるようにしてるが同じ商品は追加できないようにしていた。
Postに関連する商品としていたのでPostProductモデルとする
モデルでバリデーションを仕込む
class PostProduct < ApplicationRecord
belongs_to :user
belongs_to :post
validates :title, presence: true, uniqueness: true
validates :image, presence: true, uniqueness: true
validates :product_url, presence: true, uniqueness: true
end
今かけているバリデーションは、
titleは空にはできず、同じ値も認めないこと
imageは空にはできず、同じ値も認めないこと
product_urlは空にはできず、同じ値も認めないこと
みたいなことを書いています。
同じ処理を書いているのでまとめちゃいましょう!
class PostProduct < ApplicationRecord
belongs_to :user
belongs_to :post
with_options presence: true, uniqueness: true do
validates :title
validates :image
validates :product_url
end
end
これでスッキリしましたね!
実際に動くかやってみたところ、ちゃんとユニークネスは動いてくれたのですがここで問題が。
このコードだと、emailや電話番号くらいにしか使えません。
これは早いもの勝ちみたいな感じであるuserがこのemailを使用したら他のuserは使えねーよ?みたいな処理なんです。
emailや電話番号では正直問題にはなりません。
ですが他の機能だとちょっとめんどくさくなります。
たとえばtwitterでは1つの投稿に対していろんなuserが「いいね」や「リツイート」をします。
もしそのときに最初の書き方では、投稿には1いいねしかつけられません。
そこでuniquenessでは"scope"を使うことで期待通りの動きをしてくれます。
class PostProduct < ApplicationRecord
belongs_to :user
belongs_to :post
with_options presence: true, uniqueness: {scope: :post_id} do #ここを追加
validates :title
validates :image
validates :product_url
end
end
こう書くことで、post_idがn番の中では重複した情報を入れることができませんよ!となります。
つまりpost_idが1番と2番では同じ商品を追加することができるということになりました!