はじめに
現在webアプリ制作に携わらせていただいている中で調べて学んだことをアウトプットしていきたいと思います。
よろしくお願いいたします。
開発環境
Rails 6.0.3
Ruby 3.0.1
参考記事
Active Record バリデーション
Railsで特定の条件下で走るバリデーションを作りたい
どうしたいか
新規質問投稿時に、3種類のタグから当てはまるタグを複数選択できるようになっているが、「投稿時にタグを1つは必ず選択させる」
ようなバリデーションを構築したい。
ER図
questionsテーブルにlabelsテーブル、categoriesテーブル 、kindsテーブルがそれぞれ多対多の関係で紐づいています。
結果
class Question < ApplicationRecord
#それぞれのテーブルに中間テーブルを作り多対多の関係にしています
has_many :labellings, dependent: :destroy
has_many :labels, through: :labellings
has_many :category_labellings, dependent: :destroy
has_many :categories, through: :category_labellings
has_many :kind_labellings, dependent: :destroy
has_many :kinds, through: :kind_labellings
validates :title, presence: true
# selected_label?メソッドがtrueの場合にバリデーションチェック
validates :label_ids, presence: { message: "ラベルは必ず1つ選んでください"}, if: :selected_label?
def selected_label?
category_ids.empty? && kind_ids.empty?
end
end
考え方を変えればもう少し早く答えにたどり着いていたかもしれません。
考え方を変え、「3種類のラベルが全て空ではいけない」
⇒「2種類のラベルが空の時、1種類のラベルは必須」
この考えにたどり着き、「category_idsとkind_idsが空の時、label_idsが空では保存できない」
という実装を思いつきました。
あとは参考記事をもとに、presence: { message: "タグを1種類は選択してください" }
の部分でオリジナルのメッセージに変更。
if: :method
if分岐のオプションを使用して、method
メソッドを作り条件分岐を設定ました。
method
ではcategory_ids
とkind_ids
の値があるか確認し両方値がない場合にtrue
を返します。
最後に
見え方や考え方を変えることの大切さを改めて感じました。考え方が固執してしまわないように「逆に考えるんだ!」の言葉を胸に開発を続けます。