What wrong in this nested form?

I have:

class Company < ActiveRecord::Base
has_many :categorizations
has_many :categories, :through => :categorizations
has_many :managements
has_many :managers, :through => :managements
has_many :tenders
has_many :documents, :dependent => :destroy

accepts_nested_attributes_for :managers
accepts_nested_attributes_for :documents
accepts_nested_attributes_for :categorizations

then the form is:

= semantic_form_for @company do |f|
= f.input :name
= f.semantic_fields_for :manager do |manager|
= manager.inputs :name, :fiscal_code, :city, :zip_code, :address,
:street_number, :tel, :email

when I submit the form raise the error:

unknown attribute: manager

{“utf8”=>“✓”,
“authenticity_token”=>“V5GsRKLK8cRrGuUh2Jv4DB9wSYWG8ASCxHkd0Ur3o8s=”,
“company”=>{“manager”=>{“name”=>"",
“fiscal_code”=>"",
“city”=>"",
“zip_code”=>"",
“address”=>"",
“street_number”=>"",
“tel”=>"",
“email”=>""}},
“commit”=>“Create Company”}

I think there is nothing wrong but perhaps I miss something.

On Tue, Jan 10, 2012 at 11:33 AM, Mauro [email protected] wrote:

accepts_nested_attributes_for :managers

“zip_code”=>“”,
“address”=>“”,
“street_number”=>“”,
“tel”=>“”,
“email”=>“”}},
“commit”=>“Create Company”}

I think there is nothing wrong but perhaps I miss something.

If I am not mistaken, accepts_nested_attributes_for :managers
adds a setter method of the style company.managers_attributes=

I think your hash that is coming in from the Submit tries to do
company.manager= {“name”

=>“”,
“fiscal_code”=>“”,
“city”=>“”,
“zip_code”=>“”,
“address”=>“”,
“street_number”=>“”,
“tel”=>“”,
“email”=>“”}

and Rails complains that ‘manager’ is not an attribute of company
(really saying that the Company#manager= methods is not defined).

To validate this hypothesis, try something like, e.g. in rails console

Company.new.methods.grep(/manager/)

and check which exact methods are available for ‘manager*’ on the
Company
class.
I would expect you see there:

[… :managers_attributes=, …]

I think (not sure) a second problem is that the has_many requires an
array
there …

So, you should change your form to create parameters like this:

“company”=>{“managers_attributes”=>[ # key changed; changed into array
{“name”=>“P”,
“fiscal_code”=>“1”,
“city”=>“2560”,
…},
{“name”=>“S”,
“fiscal_code”=>“2”,
“city”=>“2500”,
…}]},

Also see:

Which shows as example:

class Member < ActiveRecord::Base
has_many :posts
accepts_nested_attributes_for :postsend

You can now set or update attributes on an associated post model through
the attribute hash.

For each hash that does not have an id key a new record will be
instantiated, unless the hash also contains a _destroy key that
evaluates
to true.

params = { :member => {
:name => ‘joe’, :posts_attributes => [
{ :title => ‘Kari, the awesome Ruby documentation browser!’ },
{ :title => ‘The egalitarian assumption of the modern citizen’ },
{ :title => ‘’, :_destroy => ‘1’ } # this will be ignored
]
}}

Not entirely sure, but I think this is your problem.

Peter


Peter V.
http://twitter.com/peter_v
http://rails.vandenabeele.com

On 10 January 2012 12:15, Peter V. [email protected]
wrote:

has_many :documents, :dependent => :destroy
= manager.inputs :name, :fiscal_code, :city, :zip_code, :address,
“fiscal_code”=>“”,

“address”=>“”,
Company.new.methods.grep(/manager/)

and check which exact methods are available for ‘manager*’ on the Company
class.
I would expect you see there:

[… :managers_attributes=, …]

Here is the grep result:

[:before_remove_for_managers=, :after_remove_for_managers,
:after_add_for_managers?, :autosave_associated_records_for_managers,
:manager_ids=, :after_remove_for_managers?,
:validate_associated_records_for_managers,
:before_remove_for_managers?, :before_add_for_managers,
:after_add_for_managers=, :before_add_for_managers?, :managers,
:before_add_for_managers=, :after_remove_for_managers=,
:after_add_for_managers, :managers=, :before_remove_for_managers,
:manager_ids]

there is a method managers so I changed

manager.semantic_fields_for :manager
to
manager.semantic_fields_for :managers

and in the controller

@company.managers.build

now it seems to work.
Thank you.

On 10 January 2012 11:43, Mauro [email protected] wrote:

But now I have a question:

if I do semantic_fields:_for :manager
without doing @company.managers.build
I see the manager form.
Why I see the manager form?
Do fields_for :manager call the manager controller?

Look in development/log to see what actions are being called and what
is being rendered. Also have a look at the Rails Guide on debuging.
That will show you how to use ruby-debug to break into your code and
see what is happening.

Colin

On Tue, Jan 10, 2012 at 1:12 PM, Colin L. [email protected]
wrote:

is being rendered. Also have a look at the Rails Guide on debugging.
That will show you how to use ruby-debug to break into your code and
see what is happening.

Actually, to get ruby-debug working on Rails 3.1.x with ruby 1.9.3-p0 I
had
to
play quite some tricks …

http://rails.vandenabeele.com/blog/2011/12/21/installing-ruby-debug19-with-ruby-1-dot-9-3-on-rvm/

Is that normal, or did I overlook something trivial ?

Peter

But now I have a question:

if I do semantic_fields:_for :manager
without doing @company.managers.build
I see the manager form.
Why I see the manager form?
Do fields_for :manager call the manager controller?

On Tue, Jan 10, 2012 at 12:36 PM, Mauro [email protected] wrote:

has_many :managers, :through => :managements
= f.input :name
“authenticity_token”=>“V5GsRKLK8cRrGuUh2Jv4DB9wSYWG8ASCxHkd0Ur3o8s=”,
I think there is nothing wrong but perhaps I miss something.
“city”=>“”,
To validate this hypothesis, try something like, e.g. in rails console
Here is the grep result:

Did you remove the line

accepts_nested_attributes_for :managers

to obtain this result above? Otherwise, I don’t understand why the
method :managers_attributes= does not show in the list …

there is a method managers so I changed

manager.semantic_fields_for :manager
to
manager.semantic_fields_for :managers

and in the controller

@company.managers.build

Do you mean you are now building a new manager from the hash, like:

@company.managers.build(params[:company][:managers]) #untested, not
exactly
sure

This may indeed work. But then you are not using the
accepts_nested_attributes_for functionality… It may be
better to stick with accepts_nested_attributes_for and
adapt your form to generate the managers_attributes hash.

But maybe I misunderstood …

Peter

Did you remove the line

accepts_nested_attributes_for :managers

perhaps it’s my mistake, sorry.
Company.new.grep(/manager/)

[:before_remove_for_managers=, :after_remove_for_managers,
:after_add_for_managers?, :autosave_associated_records_for_managers,
:manager_ids=, :after_remove_for_managers?,
:validate_associated_records_for_managers,
:before_remove_for_managers?, :before_add_for_managers,
:after_add_for_managers=, :before_add_for_managers?,
:managers_attributes=, :managers, :before_add_for_managers=,
:after_remove_for_managers=, :after_add_for_managers, :managers=,
:before_remove_for_managers, :manager_ids