0

現在、accepts_nested_attributes_for Features という顧客フォームがあります。これらの機能はいくつでもありますが、これを簡単にするために、名前、姓、生年月日であると仮定します (これが EAV であることの問題を認識しています - これについてコメントがある場合は、この件に関する私の他の質問を参照してください)。

私のコントローラーには、次のものがあります。

3.times {@customer.features.build}

これは正常に機能し、期待どおりに保存される 3 つの機能を構築します。ただし、私が望むのは、ビュー内のビルドされた機能ごとに機能タイプを指定することです。私のビューは現在次のようになっています。

<%= customer.fields_for :features do |features_builder| %>
  <%= render :partial => "features/fixed_feature", :locals => {:feature => features_builder, :fixed_feature_type => "First Name", :form_actions_visible => false} %>
<% end -%>

予想どおり、これにより 3 つの First Name フィールドが作成されます。私が望むのは、次のように 3 つの異なるタイプの機能を指定できるようにすることです。

<%= customer.fields_for :features do |features_builder| %>
  <%= render :partial => "features/fixed_feature", :locals => {:feature => features_builder, :fixed_feature_type => "First Name", :form_actions_visible => false} %>
  <%= render :partial => "features/fixed_feature", :locals => {:feature => features_builder, :fixed_feature_type => "Last Name", :form_actions_visible => false} %>
  <%= render :partial => "features/fixed_feature", :locals => {:feature => features_builder, :fixed_feature_type => "Date of Birth", :form_actions_visible => false} %>
<% end -%>

上記のコードは、インスタンスごとに 3 つのフィールドを作成しようとしているため、明らかに機能しません。私が必要としているのは、fields_for ループのインデックスです。これにより、各パーシャルを反復して if 句を追加できるため、1 回だけ起動し、それぞれが機能の異なるインスタンスで起動します。

誰かがこれを行う最善の方法を示すことができますか? 検索後、fields_for ループのインデックスを取得する方法が見つからないようです。

編集: 明確にするために、最初のコメントに従って: コントローラーによって構築された機能ごとに 1 つずつ、3 つの機能をページにレンダリングしたいと思います。各機能を別々にレンダリングしたいと思います (上記のコードで :fixed_feature_type に渡された異なるローカル変数を使用)。これを行うための最良の方法を探しています。

EDIT 2:これを行う別の方法は、コントローラーでネストされた属性を動的に構築することであることを認識しています(最初に一度に3つ構築するのではなく)-これを行う方法はありますか?

EDIT 3:これを動的に行う方法を探すのに時間を費やした後、Railscast の次のようなヘルパー メソッドを見つけました。

def link_to_add_fields(name, f, association)
  new_object = f.object.class.reflect_on_association(association).klass.new
  fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
    render(association.to_s.singularize + "_fields", :f => builder)
  end
  link_to_function(name, h("add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")"))
end

さまざまな機能フィールドを追加できるようにするこのようなヘルパー メソッドを定義できるようです。現在の状況に合わせてこれを変更する方法に関する提案があれば、喜んで回答としてマークします。

4

1 に答える 1

2

パーシャルのレンダリングをカスタムヘルパーに移動することでこれを克服することができました。これにより、必要に応じてオブジェクトを動的に構築できました。

編集:要求に応じて、私のコードは次のとおりです:

application_helper.rbファイルに次のコードを追加しました。

module ApplicationHelper

  def add_feature_fields(feature_types, object_form_builder, actions_visible)
    feature_types.length.times {object_form_builder.object.features.build}
    i = -1
    object_form_builder.fields_for :features do |features_builder|
      i = i + 1
      render :partial => "features/fixed_feature", :locals => {:feature => features_builder, :fixed_feature_type => feature_types[i], :form_actions_visible => actions_visible}
    end
  end
end

私の見解では、このヘルパーをそのように呼んでいます:

<%= add_feature_fields(["First Name", "Last Name", "Date of Birth"], customer, false) %>

これにより、配列にアイテムを追加するだけで、モデル(この場合は人)に必要な数の機能を追加できます。

お役に立てれば!

編集:'features / _fixed_feature.html.erb'

<%= feature.hidden_field :feature_type_id, :value => FeatureType.where(:value => fixed_feature_type).first.id %>
<fieldset>
        <div class="control-group">
        <label class="control-label"><Value><%= fixed_feature_type %></label>
        <div class="controls">
            <%= feature.text_field :value, :class => 'input-large' %>
        </div>
    </div>
    <% if form_actions_visible == true %>
        <div class="form-actions">
            <%= content_tag :button, :type => :submit, :class => "btn btn-info" do -%>
                Save Changes
            <% end -%>
            <%= content_tag :button, :type => :cancel, :class => "btn btn-warning" do -%>
                Cancel
            <% end -%>
        </div>
    <% end %>
</fieldset>

これについて特に特別なことはありません。ヘルパーから渡されたローカル変数を使用して、「機能タイプ」ボックスと値ボックスを必要とせずにラベルなどをレンダリングします(値ボックスのみをレンダリングするため、タイプは固定されています)。

コメントによると、さまざまなモデルの機能を追加したい場合は、ヘルパーをもう一度呼び出して「顧客」の部分を変更します(これはフォームビルダーです。より一般的には「f」ですが、よりセマンティックな命名を好みます)。

于 2012-08-22T21:22:49.260 に答える