Как вы передаете параметры через fields_for?

Я пытаюсь запустить это..

- f.fields_for :referrals do |qf|

Но я хотел бы пройти и это, @organization.referrals.select{|ref|ref.new_record?}. Это делается для того, чтобы передаваемые формы были исключительно новыми объектами, а не более старыми.

Я пытался это сделать..

- f.fields_for :referrals do |qf|
  - if qf.object.new_record?
    = render :partial => 'referral_fields', :locals => {:qf => qf}

Это позволяет правильно отображать его в представлении, но параметры по-прежнему заполняются каждым ранее созданным вложенным объектом.

Это наводит меня на мысль, что мне нужно передать эту опцию в самой инструкции fields_for.

Я также пробовал это:

- f.fields_for @organization.referrals.select{|ref|ref.new_record?} do |qf|
  = render :partial => 'referral_fields', :locals => {:qf => qf}

А также это :

- f.fields_for :referrals, @organization.referrals.select{|ref|ref.new_record?} do |qf|
  = render :partial => 'referral_fields', :locals => {:qf => qf}

Первый пример покажет и позволит передать только один объект. Где моя форма должна разрешить динамическое количество повторяющихся вложенных форм.

Второй будет отображать и передавать все вложенные объекты

Информация о приложении

#organization.rb
has_many  :referrals
accepts_nested_attributes_for :referrals, :reject_if => proc { |attributes| attributes.all? { |k, v| v.blank? } }, :allow_destroy => true
#referral.rb
belongs_to :organization
#referrals_controller.rb
def new
  2.times { @organization.referrals.build }
  ....
def create
  @referral = Referral.new(params[:referral])
  if @referral.valid? && @organization.referrals << @referral
    flash[:notice] = "Referrals saved."
    redirect_to new_organization_referrals_path(@organization)
  else
    render :action => :new, :layout => 'manage'
  end
end

person Trip    schedule 27.10.2010    source источник


Ответы (1)


Вот что вы хотите:

- f.fields_for :referrals, @organization.referrals.select{|ref|ref.new_record?} do |qf|
  = render :partial => 'referral_fields', :locals => {:qf => qf}

Первый параметр — это имя ассоциации, которое нужно рельсам, чтобы знать, как структурировать параметры. Если вашим первым параметром является коллекция, то rails обычно может вывести имя ассоциации из этой коллекции.

Однако ваша коллекция была отфильтрована в обычный массив, где связь не может быть так легко установлена. Таким образом, вы передаете конкретную коллекцию в качестве второго параметра.

Удачи!

ОБНОВЛЕНИЕ

Я создал небольшое приложение rails для анализа проблемы, и приведенное выше решение отлично работает для меня - форма редактирования не отображает существующие рефералы, а только новые. Я опубликую соответствующий код, чтобы мы могли увидеть, где вы и я можем отличаться. Одно предостережение, это все в erb, так как я редко работаю с haml и не хочу, чтобы опечатка испортила решение :)

Мои модели:

# app/models/organization.rb
class Organization < ActiveRecord::Base
  has_many :referrals
  accepts_nested_attributes_for :referrals
end

# app/models/referral.rb
class Referral < ActiveRecord::Base
  belongs_to :organization
end

Действие редактирования моего контроллера:

# app/controllers/organizations_controller.rb
class OrganizationsController < ApplicationController
  def edit
    @organization = Organization.find(params[:id])
    2.times { @organization.referrals.build }
  end
end

Мои взгляды:

# app/views/organizations/edit.html.erb
<h1>Editing <%= @organization.name %></h1>

<% form_for(@organization) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>

  <% f.fields_for :referrals, @organization.referrals.select{|ref| ref.new_record?} do |referral_fields| %>
    <%= render :partial => 'referral', :locals => {:f => referral_fields} %>
  <% end %>

  <p>
    <%= f.submit %>
  </p>
<% end %>

# app/views/organizations/_referral.html.erb
<p>
  <%= f.label :name, 'Referral Name' %><br />
  <%= f.text_field :name %>
</p>

Конечно, я только что прочитал ваши новые комментарии, и, возможно, вам это больше не нужно. О, ладно, больше документации для потомков :)

person Jaime Bellmyer    schedule 27.10.2010
comment
Нет, не будет работать. Это показывает и передает все вложенные объекты в параметры. - person Trip; 27.10.2010
comment
какую версию рельсов вы используете? - person Jaime Bellmyer; 27.10.2010
comment
Рельсы -v=2.3.5 . Я думаю, что причина, по которой он не работает, заключается в том, что когда вызывается fields_form, он технически считается «несохраненным». - person Trip; 27.10.2010
comment
Извините, я пытался дать вам решение на основе документов, но на самом деле я соберу пример. Вернусь через несколько :) - person Jaime Bellmyer; 27.10.2010
comment
Ты удивительный! :D Я даже пробовал это Referral.all.select{|ref|ref.org_name=nil} . Даже это возвращает их всех. Но! Если я делаю Referral.first или @organization.referral.first, то отображается только это. Так что это действительно работает для передачи параметров, просто ни одного из тех, которые мне нужны. Эй, большое спасибо, Хайме! - person Trip; 27.10.2010
comment
Далее... Если я поставлю -debugger прямо перед оператором fields_for и напишу @organization.referrals.select{|ref|ref.new_record?}, все будет работать так, как и ожидалось. но как только он достигает фактического оператора, отображаются все вложенные объекты. - person Trip; 27.10.2010
comment
Чтобы еще раз проверить, вы пытаетесь сделать так, чтобы форма реферала только отображалась для новых рефералов? Потому что вы явно не хотите, чтобы люди редактировали существующие рефералы. Я правильно понял, или я что-то упускаю? - person Jaime Bellmyer; 27.10.2010
comment
Я обновил свой ответ, включив в него все фрагменты кода из примера приложения, которое я создал для этой проблемы. Похоже, это все еще немного глючит для вас, поэтому я надеюсь, что это поможет. - person Jaime Bellmyer; 27.10.2010
comment
Да у тебя правильно. Так странно. Могу поспорить, что это вызвано каким-то странным экземпляром модели. Параметры параметров редко реагируют на что-либо, что я пишу, если только я не набираю что-то вроде @oragnization.find(1231), которого не существует, поэтому он терпит неудачу. Иначе ни на что не реагирует. - person Trip; 27.10.2010
comment
Интересно, имеет ли значение, где я встраиваю какой контроллер. Теперь я делаю это в представлении, а также пробовал в referrals_controller. Без разницы.. Попробую сделать кастомную коллекцию. - person Trip; 27.10.2010