2012-03-27 2 views
4

У меня есть 2 модели пользователя и адреса.Вложенные формы Rails

class User < ActiveRecord::Base 
    has_many :addresses 
    accepts_nested_attributes_for :addresses 
end 

class Address < ActiveRecord::Base 
    belongs_to :user 
end 

Мой контроллер

def new 
    @user = User.new 
    @user.addresses << Address.new 
    @user.addresses << Address.new 
    end 

    def create 
    @user = User.new(params[:user]) 
    if @user.save 
     #do something 
    else 
     render 'new' 
    end 
    end 

И мой взгляд

<%= form_for @user do |f| %> 
    <%= f.label :name %> 
    <%= f.text_field :name %> 
     <%= f.fields_for :addresses do |a| %> 
     <p> Home </p> 
     <%= a.text_field :state %> 
     <%= a.text_field :country%> 
     <%= a.text_field :street %> 
     <p> Work </p> 
     <%= a.text_field :state %> 
     <%= a.text_field :country%> 
     <%= a.text_field :street %> 
     <% end %> 
    <% end %> 
    <% end %> 

Моя проблема в том, я получаю только последнее состояние, страна, улица введенную в Params.

"addresses_attributes"=>{"0"=>{"street"=>"test", "state"=>"test",, "country"=>"test"}, 
"1"=>{"street"=>"", "state"=>"", "country"=>""}} 

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

+0

Что значит только последнее? вывод, который вы показываете здесь, ясно показывает, что вы получаете оба. addresses_attributes [0] и addresses_attributes [1] – Faisal

+0

да, но я заполнил все поля и только последние 3, которые были отправлены. – lesce

+0

Пример: первые 3 поля, заполненные «test0», а последние 3 - «test». – lesce

ответ

5

rails API говорит, что fields_for будет повторяться им по каждому элементу в коллекции адресов.

Я бы предложил добавить ярлык на ваши адреса (например, «Работа, дом» и т. Д.). И тогда он должен работать сам по себе. И с этим ярлыком вы немного более гибкие, если хотите добавить больше адресов.

<%= f.fields_for :addresses, @user.addresses do |a| %> 
    <p> <%= a.object.label %> </p> 
    <%= a.text_field :state %> 
    <%= a.text_field :country%> 
    <%= a.text_field :street %> 
    <% end %> 
+0

ok Я попробовал то, что вы сказали, и я получил неопределенный метод 'is_home_address 'для nil: ошибка NilClass, любые идеи? – lesce

+0

Не могли бы вы предоставить дополнительную информацию? некоторые номера строк и код arround это число? Мне довольно сложно всегда угадывать ошибки: P – klump

+0

ok Я исправил ошибку, обернув форму в файле @ user.addresses.each do | address | и добавляя адресный объект к полям_адрес: адреса, адрес .... и теперь я могу получить доступ к объекту ... но параметры изменили параметры [: user] [: address] и отправлен только один адрес. – lesce

3

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

def new 
    @user = User.new 
    @user.addresses.build(address_type: 'Home') 
    @user.addresses.build(address_type: 'Work') 
end 

Тогда в виде:

<%= form_for @user do |f| %> 
    <%= f.label :name %> 
    <%= f.text_field :name %> 
    <%= f.fields_for :addresses do |a| %> 
     <%= a.hidden_field :address_type %> 
     <p><%= a.object.address_type %></p> 
     <%= a.text_field :state %> 
     <%= a.text_field :country%> 
     <%= a.text_field :street %> 
    <% end %> 
    <% end %> 
<% end %> 

a.object ссылаться на объект адреса.

+0

ok Я попробовал то, что вы сказали, и я получаю неопределенный метод 'is_home_address 'для nil: ошибка NilClass, любые идеи? – lesce

+0

Вы мигрировали address_type в db? Эта ошибка возникает при посещении формы? Я обновил свой ответ, чтобы добавить скрытое поле в address_type, чтобы он сохранялся до db. Если у вас все еще есть проблемы, попробуйте отладить с помощью: <% = debug a.object%>. –

+0

Да, проблема в том, что a.object равен нулю. – lesce