How to use activemodel collection.build for a has_many :through association

Hi all,

In my controller I am doing the following to populate a nested form for
a
has_many through association:

def new
   @specification = Specification.new

Component.find_each.each do |component|
  @specification.component_specifications.build(:component_id =>

component.id)
end

The idea being whenever someone creates or edits a form, it will be
populated with all components at that time so that when they save those
components that specification will be associated with the newly created
specification. The problem I am having is I can’t work out how to pass
component name to display in my form for the as yet nonexistent
component_specification as it is not accessible through the
ComponentSpecification model.

My models:

class Specification < ActiveRecord::Base
attr_accessible :description, :name,
:component_specifications_attributes

validates :name, :presence => true, :uniqueness => true

has_many :component_specifications
has_many :components, :through => :component_specifications

accepts_nested_attributes_for :component_specifications,
:allow_destroy
=> true
end

class ComponentSpecification < ActiveRecord::Base
attr_accessible :note, :colour, :brand, :components

has_many :components

belongs_to :specification
end

class Component < ActiveRecord::Base
attr_accessible :description, :name

belongs_to :component_specifications

validates :name, :presence => true, :uniqueness => true
end

Thanks in advance,
James

On 21 July 2013 18:28, James G. [email protected] wrote:

component.id)
Don’t use .new or .build in the view, do it in the controller so that
everything is prepared before rendering the view. The view code
should only be concerned with displaying the data.

end

The idea being whenever someone creates or edits a form, it will be
populated with all components at that time so that when they save those
components that specification will be associated with the newly created
specification. The problem I am having is I can’t work out how to pass
component name to display in my form for the as yet nonexistent
component_specification as it is not accessible through the
ComponentSpecification model.

I have no idea what you mean by the last sentence. But as I said
above you should be doing this in the controller anyway.

My models:

class Specification < ActiveRecord::Base

You said in the title ActiveModel, (well actually you said activemodel
wihch would be something different again) but I see you meant
ActiveRecord. When asking questions it is important to get the
details right.

Colin

On 23 July 2013 08:23, Colin L. [email protected] wrote:

  @specification.component_specifications.build(:component_id =>

component.id)

Don’t use .new or .build in the view, do it in the controller so that
everything is prepared before rendering the view. The view code
should only be concerned with displaying the data.

Sorry, I seem to have suffered from brain fade when I wrote the above
code, it is in the controller. You might want to put the second part
in a method of the Specification model however. I am not sure why you
are using find_each but that is a different issue.

I have no idea what you mean by the last sentence. But as I said
above you should be doing this in the controller anyway.

I still don’t understand what the problem you are describing is here
though. Why can’t you just say
@specification.component_specifications?

Colin

On 21 July 2013 18:28, James G. [email protected] wrote:

component.id)
My models:
true
end

class ComponentSpecification < ActiveRecord::Base
attr_accessible :note, :colour, :brand, :components

has_many :components

I think that should be belongs_to :component, unless my brain is fading
again.

belongs_to :specification
end

class Component < ActiveRecord::Base
attr_accessible :description, :name

belongs_to :component_specifications

and that should be has_many

Colin

On Sunday, 21 July 2013 13:28:38 UTC-4, James G. wrote:

  @specification.component_specifications.build(:component_id =>

component.id)
end

One note on this: I’m not sure what the find_each is getting you here.
If
there are enough records to make it important to find them in batches,
building a new ComponentSpecification for each is going to be a bad
idea.

The idea being whenever someone creates or edits a form, it will be

attr_accessible :description, :name, :component_specifications_attributes

class ComponentSpecification < ActiveRecord::Base
attr_accessible :note, :colour, :brand, :components

has_many :components

This doesn’t match the code you’re using above - setting component_id
isn’t going to load this association. Is it possible this should be a
belongs_to :component instead?

class Component < ActiveRecord::Base
attr_accessible :description, :name

belongs_to :component_specifications

Again, I think this is the wrong way round - I’m guessing your intended
data model is that one Specification can have many Components, with
ComponentSpecifications acting as a join table…

–Matt J.