32

buildfields_for、およびを使用accepts_nested_attributes_forして、新しい登録と同じフォームに新しい登録メモを作成しています (多くの登録メモがあります)。偉大な。

問題: 既存の登録の編集フォームで、別の新しい登録メモを作成したいのですが、既存の登録メモごとにフィールドを表示したくありません。

私はこれを持っています

class Registration < ActiveRecord::Base
  attr_accessible :foo, :bar, :registration_notes_attributes
  has_many :registration_notes
  accepts_nested_attributes_for :registration_notes
end

この

class RegistrationsController < ApplicationController
  def edit
    @registration = Registration.find(params[:id])
    @registration.registration_notes.build
  end
end

ビューで私はこれをやっています:

<%= form_for @registration do |r| %>
  <%= r.text_field :foo %>
  <%= r.text_field :bar %>
  <%= r.fields_for :registration_notes do |n| %>
    <%= n.text_area :content %>
  <% end %>
<% end %>

また、新しい登録メモ (良い)その登録の既存の各登録メモ (いいえ) 用の空白のテキスト領域を作成しています。

その登録用の新しいメモのみを作成し、既存のものはそのままにしておく方法はありますか?

4

4 に答える 4

78

編集:私の以前の回答(以下を参照)は、あまり良くないため、私を悩ませていました(まだ他のすべてをregistration_notes不必要にループしています)。API をもう少し読んだ後、OP が必要とする動作を取得する最善の方法は、次のように置き換えることです。

<%= r.fields_for :registration_notes do |n| %>

と:

<%= r.fields_for :registration_notes, @registration.registration_notes.build do |n| %>

fields_forオプションで、インラインでビルドされるビルダー ( API を参照) に渡す特定のオブジェクトである 2 番目のパラメーターを取ります。ただし、実際には、フォームではなくコントローラーで新しいメモを作成して渡す方が良いでしょう (ロジックをビューの外に移動するだけです)。


元の回答(私はとても近かったです):

明確にするために、編集フォームに新しいネストされた登録メモを含めたいですか (他の既存のものは無視しますか)? 私はこれをテストしていませんが、次のように置き換えることでテストできるはずです:

  <%= r.fields_for :registration_notes do |n| %>

と:

  <%= r.fields_for @registration.registration_notes.build do |n| %>

編集:さて、動作しない私自身の簡単なテストからですが、代わりに次のことができます:

<%= r.fields_for :registration_notes do |n| %>
  <%= n.text_area :content if n.object.id.nil? %>
<% end %>

これは、登録メモの ID が nil の場合 (つまり、まだ保存されていない場合) にのみテキスト領域を追加します。

また、私は実際にこれを最初にテストしましたが、うまくいきます;)

于 2013-02-14T22:14:29.530 に答える
4

edit アクションで新しい登録フォームを作成したい場合は、新しい registration_note オブジェクトをインスタンス化するだけです。現在、フォームは既存の登録オブジェクト用です。

これがあなたが望むものだと思います:

class RegistrationsController < ApplicationController
  def edit
    @new_registration_note = RegistrationNote.new
    @registration = Registration.find(params[:id])
    @registration.registration_notes.build
  end
end

ビューでは、登録レコード ID を参照する非表示のパラメーターを渡す必要があります。

<%= form_for @new_registration_note do |r| %>
  <%= r.hidden_field :registration_id, :value => @registration.id  %>
  <%= r.text_area :content  %>
<% end %>

これで、 に属する 新しい登録メモを作成できます@registrationregistration_notesテーブルに登録を指す列があることを確認してください。アソシエーションについて詳しくは、http: //guides.rubyonrails.org/association_basics.htmlをご覧ください。

于 2013-02-14T22:04:50.530 に答える
4

「Zaid Crouch」からのアプローチの唯一の問題は、フォームにエラーフィールドがある場合、フォームにエラーフィールドがあることです。ページがリロードされた後、明確でブームになります。フォームには何も入力されていません。フォームが20または30のフィールドの場合、もちろんひどいユーザーエクスペリエンスになると想像できますか

検証モデルで動作する私のソリューションは次のとおりです。

class Registration < ActiveRecord::Base
  attr_accessible :foo, :bar, :registration_notes_attributes
  has_many :registration_notes
  has_one :new_registration, class_name: 'RegistrationNote'
  accepts_nested_attributes_for :new_registration
end

class RegistrationsController < ApplicationController
  def edit
   @registration = Registration.find(params[:id])
   @registration.build_new_registration
  end
end

<%= form_for @registration do |r| %>
  <%= r.text_field :foo %>
  <%= r.text_field :bar %>
  <%= r.fields_for :new_registration do |n| %>
    <%= n.text_area :content %>
  <% end %>
<% end %>

検証とトランザクションで同じ動作を確認したい場合は、私の例で simple_form を使用しています。ここで完全な投稿を見てください: http://elh.mx/ruby/using-simple_form-for-nested-attributes-models -in-a-has_many-relation-for-only-new-records/

于 2015-06-10T17:20:23.930 に答える