form_withのパラメーターの行き先の仕組み
form_withのパラメーターの行き先の仕組み
[form_with]を使うと、パラメーターの行き先をcreateアクション(POST)やupdateアクション(PATCH)などと良い感じで分けてくれるが、この仕組みを説明します。
[app/views ファイル] <%= form_with model: @user, url: admin_user_path(@user), local: true do |f| %>
Railsは、form_withに渡しているmodelのインスタンスの状態を見てcreateアクション(POST)やupdateアクション(PATCH)などの行き先を判断している
persisted?というメソッドを使い、@new_recordと@destroyedの2つのインスタンス変数にアクセスして状態を確認している
@new_recordと@destroyedのインスタンス変数とは、作成したオブジェクトが持っているインスタンス変数
persisted?がtrueならPATCHへパラメーターが送られる
persisted?がfalseならPOSTへパラメーターが送られる
persisted?メソッドの挙動とオブジェクトが持つインスタンス変数は、以下のイメージ
# DBに保存済みのインスタンスと未保存のインスタンスを用意します。 >> persisted_user = User.first >> new_user = User.new # @new_recordと@destroyedというインスタンス変数を持っているのか確認します。 >> persisted_user.instance_variables # => [:@attributes, :@aggregation_cache, :@association_cache, :@readonly, :@destroyed, :@marked_for_destruction, :@destroyed_by_association, :@new_record, :@_start_transaction_state, :@transaction_state] >> new_user.instance_variables # => [:@attributes, :@aggregation_cache, :@association_cache, :@readonly, :@destroyed, :@marked_for_destruction, :@destroyed_by_association, :@new_record, :@_start_transaction_state, :@transaction_state] # それぞれのインスタンス変数の値を確認します >> persisted_user.instance_variable_get('@new_record') # => false >> persisted_user.instance_variable_get('@destroyed') # => false >> persisted_user.persisted? # => true >> new_user.instance_variable_get('@new_record') # => true >> new_user.instance_variable_get('@destroyed') # => false >> new_user.persisted? # => false # ちなみに削除済みも確認してみる >> destroyed_user = persisted_user.destroy >> destroyed_user.instance_variable_get('@new_record') # => false >> destroyed_user.instance_variable_get('@destroyed') # => true > destroyed_user.persisted? # => false
参考記事: