ActiveModelのベストプラクティスを考える
ActiveModelとは
ActiveModelとは こちら にあるように Modelと直接紐付けないような、フロントのフォームに密接に関わるバリデーションを実装する場合に便利な Module。
課題
ActiveModel
を利用シーンの一つとして、一つフォームで複数のモデルを扱うことがある。
その際によく迷うことがある。
- モデルのバリデーションが
ActiveModel
とApplicationRecord
のモデルとで重複する - データの作成と編集で
ActiveModel
のintialize
にどうやって、何を渡すか(ここらへん情報が検索してもあまり見つからなかった)
解決方法
そこで、とりあえず考えた解決方法
ActiveModel
に対象のモデル群を内包するfind
,save
,valid?
を実装ActiveModel
のバリデーションはフォーム固有のものだけを実装し、モデルで実装されているバリデーションはモデルに任せるController
はcreate
,update
はフォームの内容を,edit
の場合は保存されている内容からフォームを作成できるようにするsave
時にvalid?
を実行し、内包するモデルのバリデーションエラーとフォームのバリデーションエラーを全てフォームのエラーに追加する
以下イメージ。実際の動作確認はしてないです
class HogeController < ApplicationController der new @hoge_form = HogeForm.new() end der create @hoge_form = HogeForm.new(params[:hoge_form]) if @hoge_form.save ... else ... end end def edit @hoge_form = HogeForm.find(parmas['id']) end def update ... end ... calss HogeForm include ActiveModel attr_accessor :hoge_a, :foo_b validates :hoge_a, presence: true validates :foo_b, presence: true class << self def find(id) hoge = Hoge.find id new(hoge: hoge.attributes, foo: hoge.foo.attributes) end end def intialize(params = {}) @hoge = Hoge.new(params[:hoge]) @foo = Foo.new(params[:foo]) end def valid?(context = nil) super @hoge.valid? @hoge.errors.each do |k, v| errros.add(k, v) end @foo.valid? @foo.errors.each do |k, v| ... end def save return unless valid? return false unless @hoge.save @foo.save end end
関連のおすすめ本
- 作者: 掌田津耶乃
- 出版社/メーカー: 秀和システム
- 発売日: 2016/12/17
- メディア: 単行本
- この商品を含むブログを見る