1

私はペアと呼ばれるモデルを持っています。これは、多くの:questions を持ち、各 Question には 1 つの :answer があります。

ネストされたフォームの作成でこのレールキャストをフォローしてきましたが、「質問を追加」リンクをクリックすると、質問フィールドと回答フィールドの両方を生成したいと考えています。

Railscastをフォローした後、これが私が持っているものです:

..javascripts/common.js.coffee:

window.remove_fields = (link)->
  $(link).closest(".question_remove").remove()

window.add_fields = (link, association, content)->
  new_id = new Date().getTime()
  regexp = new RegExp("new_" + association, "g")
  $(link).before(content.replace(regexp, new_id))

application_helper.rb:

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

ビュー/ペア/_form.html.erb:

<%= simple_form_for(@pair) do |f| %>
  <div class="row">
    <div class="well span4">
      <%= f.input :sys_heading, label: "System Heading", placeholder: "required", input_html: { class: "span4" } %>
      <%= f.input :heading, label: "User Heading", input_html: { class: "span4" } %>
      <%= f.input :instructions, as: :text, input_html: { class: "span4 input_text" } %>
    </div>
  </div>

  <%= f.simple_fields_for :questions do |builder| %>
    <%= render 'question_fields', f: builder %>
  <% end %>
  <%= link_to_add_fields "<i class='icon-plus icon-white'></i> Add Another Question".html_safe, f, :questions %>
  <%= f.button :submit, "Save Pair", class: "btn btn-success" %>
<% end %>

_question_fields.html.erb パーシャル:

<div class="question_remove">
  <div class="row">
    <div class="well span4">
      <%= f.input :text, label: "Question", input_html: { class: "span4" }, placeholder: "your question...?" %>

      <%= f.simple_fields_for :answer do |builder| %>
        <%= render 'answer_fields', f: builder %>
      <% end %>
    </div>
  </div>
</div>

_answer_fields.html.erb 部分:

<%= f.input :text, label: "Answer", input_html: { class: "span4" }, placeholder: "your answer" %>
<%= link_to_function "remove", "remove_fields(this)", class: "float-right" %>

私は特に、reflect_on_association の部分で混乱しています。たとえば、.newそこを呼び出すとどのように関連付けが作成されるのでしょうか? 私は通常使用する必要があります.build

また、has_one.build_answerではなく使用しますanswers.buildが、これは jQuery 部分にとって何を意味するのでしょうか?

4

2 に答える 2

1

これを確認する 1 つの方法は、Rails コンソールでヘルパー スクリプトを実行することです。

new_object = f.object.class.reflect_on_association(association).klass.new

Form オブジェクトを取得し、それが対象となるクラス (f.object.class - この場合はpair ) を見つけてから、reflect_on_association(association) を使用して、名前付き関連付けの AssociationReflection オブジェクトを返します (からシンボルとして渡されます)。引数、つまり:質問)。

Reflect_on_all_associations を使用すると、各クラスのこれらの AssociationReflection オブジェクトをすべて表示できます。

この後、AssociationReflection が表すクラスが必要になります (クラスではなくクラスを使用するのはそのためです)。次に、クラスの新しいインスタンスを作成します。

new の代わりに build_#{association_name} または #{association_name}.builds を使用しない理由は、関連付けられたオブジェクトのインスタンスを取得するまで、関連付けが has_one か HABTM かをスクリプトが認識できないためです。追加のロジックは価値がありません。

http://api.rubyonrails.org/classes/ActiveRecord/Reflection/ClassMethods.html

ところで、改訂されたレールキャストは、関連するオブジェクトを生成する方法が少し異なりますが、考え方は同じです (この場合、フォーム オブジェクトのメソッドを送信 - 呼び出してから、関連するクラスを生成します)

new_object = f.object.send(association).klass.new

ヘルパーで 2 つのモデルを使用することについては、この線に沿ったものですか?

application_helper.rb

def link_to_add_nested_fields(name, f, association, nested_association)
   new_object = f.object.class.reflect_on_association(association).klass.new
   new_object.send(nested_association).new
   fields = f.simple_fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
     render(association.to_s.singularize + "_fields", :f => builder)
   end
   link_to_function(name, "window.add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")", class: "btn btn-inverse")
end

例えば

<%= link_to_add_fields "<i class='icon-plus icon-white'></i> Add Another Question".html_safe, f, :questions, :answer %>
于 2012-06-07T16:18:46.433 に答える