1. ホーム
  2. ruby-on-rails

[解決済み] Ruby on Railsでsimple_formを使うさまざまな方法|何が違うの?

2022-02-11 12:04:46

質問

パックの編集フォームの宛先には、以下の方法がありますが、どのような違いがあるのでしょうか?

これらの異なるアプローチは、アプリケーションの安定性にどのような影響を与えるのでしょうか?また、汎用性はありますか?

これらはどこで大きな問題になるのでしょうか?なぜ一方が他方より優れているのでしょうか?

  1. Via "method?"。 <%= simple_form_for Pack.find(params[:id]), method: :patch do |f| %>
  2. オブジェクト経由 <%= simple_form_for @pack, url: pack_path(@pack), method: :patch do |f| %>
  3. シンボル経由 <%= simple_form_for :pack, url: pack_path(@pack), method: :patch do |f| %>

どんな情報でも結構です!是非教えてください。

解決方法は?

1. と 2. - フォームヘルパーをモデルインスタンスにバインドする

2. では、メソッド呼び出しの戻り値を渡す代わりに、インスタンス変数からモデルインスタンスを参照しているという事実を除けば、基本的に同じです。

最終的には、モデルインスタンスにバインドされたフォームを得ることができます。これは、入力のvalue属性にモデルの値が含まれることを意味します。

実際、これらはすべて同じ結果になります。

<% 
  @pack = Pack.find(params[:id]) 
  pack = Pack.find(params[:id]) 

%>

<%= simple_form_for Pack.find(params[:id]), method: :patch do |f| %>
<%= simple_form_for @pack |f| %>
<%= simple_form_for pack |f| %>

しかし、ビューから直接クエリを実行することは避けるべきですので、最初の方法はあまり好ましくありません。ビューはコントローラからデータを受け取り、それを使ってHTMLを作成し、できるだけシンプルで宣言的であるべきです。もうひとつの大きな問題は .findActiveRecord::RecordNotFoundError が無効である場合、コントローラ内でもっと早く発見されるはずでした。

3. フォームヘルパーをシンボルで呼び出す。

<%= simple_form_for :pack, url: pack_path(@pack), method: :patch do |f| %>

これは、特定のモデルインスタンスに必ずしもバインドされることなく、quot;scoped"されたフォームを作成します。この例を見てみましょう。

<%= simple_form_for :thing do  |f| %>
  <%= f.input :name %>
<% end %>

これにより、以下のようなHTMLが生成される。

<form novalidate="novalidate" class="simple_form thing" action="/things/new" accept-charset="UTF-8" method="post">
  <input name="utf8" type="hidden" value="&#x2713;" /><input type="hidden" name="authenticity_token" value="F4r1gLuboZc1CKIdn9qac0sefxSVIvkjxk9KsD+sRl1wnVtEIKzHvWY0mPuLPvHI1Kcv3TIWD883YXHKXA+yJQ==" />
  <div class="input string required thing_name">
    <label class="string required" for="thing_name"><abbr title="required">*</abbr> Name</label>
    <input class="string required" type="text" name="thing[name]" id="thing_name" />
  </div>
</form>

備考 name="thing[name]" これは、モデルインスタンスがある場合と同じように params ハッシュを与えることを意味します。

{
   thing: {
     name: "foo"
   }
}

ほとんどの場合、モデルのインスタンスを操作することになるので、これはあまり一般的には使われませんが(少なくとも正しくありません)、検索フォームのような特殊なケースでは使い道があります。

Rails はローカル変数 @thing が、nil の場合はエラーを発生させません。この形式はエラーを隠蔽する可能性があるため、一般的にはお勧めできません。

この挙動を理解する最善の方法は ActionView::FormHelpers これは SimpleForm がその上の砂糖に過ぎません。