Skip to content


Rails many-to-many associations

The tables:


developer (...)

functional_system (...)

developers_function_systems (developer_id, functional_system_id)

I used “functional_system” instead of simply “system”, because it was giving me errors as it is one of Rails

href="http://wiki.rubyonrails.com/nails/show/ReservedWords" target="_blank">reserved words – something I don't like about

Rails.

The models


class FunctionalSystem < ActiveRecord::Base

has_and_belongs_to_many :developers

end



class Developer < ActiveRecord::Base

has_and_belongs_to_many :functional_systems

end


The View (templates)

I included the checkboxes representing developers working on the same system:


...

<% Developer.find(:all).each do |developer| %>

<li><%= check_box_tag("functional_system[developer_ids][]", developer.id, @functional_system.developers.include?

(developer))%> <%= developer.name %></li>

<% end %>

..


The Controller


...

@functional_system = FunctionalSystem.new(params[:functional_system])

...

Rails has recognized the request parameters and magically filled out the @functional_system.developers collection.

A problem occurred when I wanted to include the join_date in the association information. That is the developers_functional_systems has an additional field of “join_date”. After trying out several scenarios – I finally came
across push_with_attributes.

Adding the following lines to the controller


@functional_system = FunctionalSystem.new(params[:functional_system])



#developers collection need to be cleared. Otherwise a "Duplicate Entry" error will be returned

@functional_system.developers.clear

params[:functional_system][:developer_ids].each do |dev_id|

@functional_system.developers.push_with_attributes(Developer.find(dev_id), {"join_date" => Date.today});

end

This performs what Rails has previously done automagically. It added a new developers_functional_systems's entry
(explicitly), with the additional association info of “join_date”.

As a more friendly approach, and to make use of Rails magic, It was better off adding the “join_date” in the view.

The naming convention is a bit tricky, after several trials, this have worked:


<ul>

<% Developer.find(:all).each do |developer| %>

<li><%= check_box_tag("functional_system[developer_ids][]", developer.id,

@functional_system.developers.include?(developer)) %><%= developer.name %></li>

<input type="hidden" name="developers[join_dates][]" value="<%= Date.today %>">

<% end %>

</ul>

I'm still not sure how the hash represented by name=”developers[join_dates][]” is recognized as belonging to the current
“functional_system”. Does anyone have a clue?

Posted in Ruby.

0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.