I have these 2 models:
class User < ActiveRecord::Base
has_one :city
accepts_nested_attributes_for :city
end
class City < ActiveRecord::Base
belongs_to :user
end
This view:
<%= form_for :user,:url => users_path,:method => :post do |f| %>
<%= f.fields_for :city_attributes do |b| %>
<%= b.collection_select :id,City.all,:id,:name %>
<% end %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
So, I already have a list of cities added. I want to allow the user to
select from one of the available cities in the select. But, when I
submit the form, I get this error:
Couldn’t find City with ID=1 for User with ID=
What am I doing wrong?
On Apr 7, 8:36am, John C. [email protected] wrote:
This view:
<%= form_for :user,:url => users_path,:method => :post do |f| %>
<%= f.fields_for :city_attributes do |b| %>
<%= b.collection_select :id,City.all,:id,:name %>
<% end %>
With accepts_nested attributes this should just be f.fields_for :city
Fred
If I put f.fields_for :city, this gets generated:
and I get an AssociationMismatch saying
ActiveRecord::AssociationTypeMismatch: City(#36862620) expected, got
Hash(#21169932)
If I put f.fields_for :city_attributes, this gets generated:
Which looks more like what the nested form would accept.
On Apr 7, 10:43am, John C. [email protected] wrote:
Which looks more like what the nested form would accept.
With accepts_nested_attributes you always just use the association
name - you don’t need to mangle things. Also I’m slightly confused by
your models / form. Does a city really belong to a unique user ?
Fred
Ignore the model names and what they stand for :). They are only for
example purpose.
So, if I make my view like this:
<%= form_for :user,:url => users_path,:method => :post do |f| %>
<%= f.fields_for :city do |b| %>
<%= b.collection_select :id,City.all,:id,:name %>
<% end %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
Then I get the association mismatch:
City(#37602432) expected, got
ActiveSupport::HashWithIndifferentAccess(#32969988)
With these parameters:
{“commit”=>“Save User”,
“authenticity_token”=>“whatever”,
“utf8”=>“✓”,
“user”=>{“city”=>{“id”=>“1”},
“name”=>“as”}}
On Apr 7, 1:37 pm, John C. [email protected] wrote:
Ignore the model names and what they stand for :). They are only for
example purpose.
So, if I make my view like this:
<%= form_for :user,:url => users_path,:method => :post do |f| %>
Oh, for nested attributes to work you need an actual instance of user,
not the symbol :user
<%= f.fields_for :city do |b| %>
<%= b.collection_select :id,City.all,:id,:name %>
<% end %>
I’m not convinced that this will play well with nested attributes.
nested attributes mostly wants to either create a new object or edit
an existing one, whereas you want to choose from a list of objects and
then edit one of those (to set the user_id)
Fred
On Apr 7, 2:19pm, John C. [email protected] wrote:
I guess it’s expecting me to build the city instance in the controller?
correct. field_for on an association that has nested attributes turned
on renders its block for each associated object.
The way I got it to work is by doing this in my model:
def city_attributes=(attribs)
self.city = City.find(attribs[:id])
end
Is there no other way?
It might be easier to just have a city_id virtual attribute rather
than trying to bend accepts_nested_attributes_for (given that you are
currently overriding all of the stuff it gives you)
Fred
If I try to pass an User instance, the select isn’t displayed. Here’s
the view now:
<%= form_for @user,:url => users_path,:method => :post do |f| %>
<%= f.fields_for :city do |b| %>
<%= b.collection_select :id,City.all,:id,:name %>
<% end %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
I guess it’s expecting me to build the city instance in the controller?
The way I got it to work is by doing this in my model:
def city_attributes=(attribs)
self.city = City.find(attribs[:id])
end
Is there no other way?
But, how would having it as a virtual attribute help? It would not be
saved to the database, so it’s value would be lost.
On Apr 7, 4:57pm, John C. [email protected] wrote:
But, how would having it as a virtual attribute help? It would not be
saved to the database, so it’s value would be lost.
because you’d define city_id= to be basically the same as the
city_attributes method you have above. It’s not very different to what
you have but allows you to get rid of the accepts_nested_attributes
and the fields_for
Fred