Note that there are some explanatory texts on larger screens.

plurals
  1. POJoin table attribute updates in Many-to-Many Relation
    primarykey
    data
    text
    <p>I have a many-to-many relation setup for a data model which deals with a problem domain of Members and Addresses. Basically a 'member' can have multiple 'addresses', think of like when you have a work address and a home address. </p> <p>I want to store additional attributes on the join table and save data, apart from the foreign key attributes. There are many examples on the net about many-to-many relations, but I've not found details/examples on storing the extra data.</p> <p>Here is the problem that i'm stuck with.</p> <p>The models are setup as:</p> <p><strong>Models</strong></p> <pre><code>class Member &lt; ActiveRecord::Base has_many :member_addresses has_many :addresses, :through =&gt; :member_addresses end class MemberAddress &lt; ActiveRecord::Base belongs_to :address # foreign key for address -&gt; address_id belongs_to :member # foreign key for member -&gt;member_id end class Address &lt; ActiveRecord::Base has_many :member_addresses has_many :members, :through =&gt; :member_addresses accepts_nested_attributes_for :members, :allow_destroy =&gt; true end </code></pre> <p>The 'accepts_nested_attributes' on the Address class is for the nested-forms.</p> <p><strong>Database Schema/Migrations</strong> The tables (simplified for posting) are defined as</p> <pre><code>create_table "addresses", :force =&gt; true do |t| t.string "firstline" t.string "state" .... end create_table "member", :force =&gt; true do |t| t.string "name" .... end create_table "member_addresses", :force =&gt; true do |t| t.integer "member_id" t.integer "address_id" t.string "address_type" end </code></pre> <p>The field 'address_type' on the join table is intended for flagging the type of the address that is associated with the member (aka; "home" or "work")</p> <p><em><strong>It is updating this field that is where I'm getting stuck.</em></strong></p> <p><strong>Controllers &amp; View</strong></p> <p>The member_controller setups the model like:</p> <pre><code>members_controller.rb def new @member = Member.new @member.addresses.build #pre-build the associated address end </code></pre> <p>Then the view for the member page <strong>new</strong> action is</p> <p>&lt;%= form_for @member do |m| %></p> <pre><code> &lt;%= m.label :first_name, "First Name"%&gt; &lt;%= m.text_field :first_name %&gt; &lt;/p&gt; &lt;%= m.fields_for :addresses do |addrform|%&gt; &lt;%= addrform.label :firstline %&gt; &lt;%= addrform.text_field :firstline %&gt; &lt;% end %&gt; &lt;br /&gt; &lt;%= label_tag 'Type of address' %&gt; &lt;%= text_field_tag 'addrtype' %&gt; &lt;br /&gt; &lt;%= m.submit "Add" %&gt;&lt;br /&gt; </code></pre> <p>&lt;% end %></p> <p>The idea is that with the 'accepts_nested_attributes' on the <strong>Member</strong> model I can enter the data on the form to add in the name and address attributes. The additional <strong>label_tag</strong> is for the data to be posted for the address type that I want to store </p> <p>So when the form is filled in the post data (form a trap) looks like:</p> <pre><code>{"utf8"=&gt;"✓", "authenticity_token"=&gt;"E0R038rcdJmBGjjxQ9nQLHGVbzM4ejA0vsEaIvqkwkE=", "member"=&gt;{"first_name"=&gt;"James", "last_name"=&gt;"SMith", "addresses_attributes"=&gt;{"0"=&gt;{"firstline"=&gt;"this is the first line"}}}, "addrtype"=&gt;"home", "commit"=&gt;"Add"} </code></pre> <p>All good - i'm getting my <strong>Member</strong> data and the <strong>Address</strong> data, as well as the additional field 'addrtype' which is to be used for carrying my additional data</p> <p>Now how to get the data into the relation or join table ? On the <strong>member_controller create action</strong> </p> <pre><code>def create # create a member with the params posted @member = Member.new(params[:member]) # get data for 'relation data' @addr_type = params[:addrtype] if @member.save! #update the relation now created with the address type @member.member_addresses.first.address_type = @addr_type # save the relationship (is this necessary?) @member.save! redirect_to members_path end </code></pre> <p>As you can see in the <strong>create</strong> I'm attempting to fill in the data on the join table and then force a save again so that the relation or association with the additional attribute is saved. </p> <p>This doesn't work, and/or I'm doing it wrong.</p> <p>Any suggestions would be most appreciated.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload