Форма вложенного объекта Rails * _attributes - PullRequest
6 голосов
/ 13 апреля 2009

Я использую Rails 2.3.2 и пытаюсь заставить форму вложенного объекта работать правильно. Я сузил свою проблему до проблемы, заключающейся в том, что Rails не устанавливает мои вложенные элементы формы с * _attributes, необходимыми для инициации обработки acceptpts_nested_attributes_for.

Код моей модели:

class Person < Party
  has_one :name, :class_name => "PersonName"
  accepts_nested_attributes_for :name, :allow_destroy => true
end

class PersonName < ActiveRecord::Base
  belongs_to :person
end

Код моего вида выглядит следующим образом (я использую HAML):

%h3 New customer
= error_messages_for :person, :person_name, :name, :country

- form_for :person, :url => collection_url, :html => {:class => 'MainForm'} do |person_form|

  - @person.build_name unless @person.name
  - person_form.fields_for :name do |name_form|
    = name_form.label :given_name, "First Name:"
    = name_form.text_field :given_name

    = name_form.label :family_name, "Last Name:"
    = name_form.text_field :family_name

  = hidden_field_tag :inviter_id, params[:inviter_id]
  = hidden_field_tag :inviter_code, params[:inviter_code]
  %p= submit_tag "Create"

= link_to 'Back', collection_url

Вместо параметров:

{"person"=>{"name_attributes"=>{"given_name"=>"Fred", "family_name"=>"Flintstone"}}, ...} 

Я получаю:

{"person"=>{"name"=>{"given_name"=>"Fred", "family_name"=>"Flintstone"}}, ...} 

В результате я получаю исключение TypeMismatch. Я следовал за документацией Райана Дейгла . Я также последовал совету этого блога и сложных форм-примеров .

Используя Firebug, я просмотрел свою форму и изменил атрибут name входных тегов с name на name_attributes. Это произвело параметры с name_attributes, и создание работало отлично.

Я застрял, так как не могу понять, почему моя форма не производит форму * _attributes имени.

Еще одна вещь, которую я попробовал, это то, что я получил complex_form_example, работающий в моей среде. Я просмотрел каждый дюйм контроллера, моделей и представлений и сравнил его с моим кодом. Я не могу найти то, что отличается. Я знаю, что это что-то маленькое, и буду признателен за любую помощь!

Спасибо!

Ответы [ 6 ]

4 голосов
/ 16 июля 2009

Почтовые задники не перенаправляются в нужное место

def new
  @person = Person.new
end

<% form_for @person do |f| %>
    <% f.fields_for :name_attributes do |p| %>
        ...
    <% end %>
<% end %>

Почтовые задники направляются в нужное место

def new
  @person = Person.new
  @person.name = PersonName.new # << this allows fields_for :relation vs :relation_attributes
end

<% form_for @person do |f| %>
    <% f.fields_for :name do |p| %>
        ...
    <% end %>
<% end %>

Нет необходимости @ person.name снова в # create

4 голосов
/ 24 апреля 2009

Попробуйте использовать реальный объект для form_for:

form_for :person => form_for @person
1 голос
/ 19 августа 2009

Я около часа боролся с точно такой же проблемой!

Следуйте шаблону nowk для нового метода в контроллере, затем поместите это в ваше представление

<% form.fields_for :name, @person.name do |name_form| %>


<% end %>

Удачи, если вы попробуете, вот что сработало для меня.

0 голосов
/ 07 сентября 2011

Я бы хотел поделиться своим решением, так как оно немного отличается - в моем случае я хочу, чтобы вложенные атрибуты были динамическими.

В новом действии:

  case params[:type]
  when "clubber"
    @account = resource.send "build_#{params[:type]}"
  when "promoter"
    @account = resource.send "build_#{params[:type]}"
  when "company"
    @account = resource.send "build_#{params[:type]}"
  when "venue_owner"
    flash[:notice] = 'We ask that venue owners register via the web. Thanks.'
    redirect_to root_path and return
  end

На мой взгляд:

= f.fields_for @account.class.name.downcase+'_attributes' do |form|

Довольно гетто, но оно работает.

0 голосов
/ 16 апреля 2009

К сожалению, я до сих пор не смог понять, почему эта форма не будет работать с вложенными объектными формами. Я сократил его до самых простых данных и начал с использования примера сложной формы в качестве начала. Я прекратил использовать active_presenter для сбора данных x-объекта из формы. Я еще вернусь к вложенным формам объектов в форме. Спасибо за вашу помощь.

0 голосов
/ 13 апреля 2009

Не знаю, почему это не работает, но в качестве обходного пути вы можете просто использовать params [: name] в вашем контроллере # create метод для обновления записи о человеке.

person = Person.new(params[:person])
person.name << PersonName.new(params[:name])
...