Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to access rails join model attributes when using has_many :through

I have a data model something like this:

# columns include collection_item_id, collection_id, item_id, position, etc
class CollectionItem < ActiveRecord::Base
  self.primary_key = 'collection_item_id'
  belongs_to :collection
  belongs_to :item
end

class Item < ActiveRecord::Base
  has_many :collection_items
  has_many :collections, :through => :collection_items, :source => :collection
end

class Collection < ActiveRecord::Base
  has_many :collection_items, :order => :position
  has_many :items, :through => :collection_items, :source => :item, :order => :position
end

An Item can appear in multiple collections and also more than once in the same collection at different positions.

I'm trying to create a helper method that creates a menu containing every item in every collection. I want to use the collection_item_id to keep track of the currently selected item between requests, but I can't access any attributes of the join model via the Item class.

def helper_method( collection_id )
  colls = Collection.find :all
  colls.each do |coll|
    coll.items.each do |item|
# !!! FAILS HERE ( undefined method `collection_item_id' )
      do_something_with( item.collection_item_id )
    end
  end
end

I tried this as well but it also fails with ( undefined method `collection_item' )

do_something_with( item.collection_item.collection_item_id )

Edit: thanks to serioys sam for pointing out that the above is obviously wrong

I have also tried to access other attributes in the join model, like this:

do_something_with( item.position )

and:

do_something_with( item.collection_item.position )

Edit: thanks to serioys sam for pointing out that the above is obviously wrong

but they also fail.

Can anyone advise me how to proceed with this?

Edit: -------------------->

I found from online documentation that using has_and_belongs_to_many will attach the join table attributes to the retreived items, but apparently it is deprecated. I haven't tried it yet.

Currently I am working on amending my Collection model like this:

class Collection < ActiveRecord::Base
  has_many :collection_items, :order => :position, :include => :item
  ...
end

and changing the helper to use coll.collection_items instead of coll.items

Edit: -------------------->

I've changed my helper to work as above and it works fine - (thankyou sam)

It's made a mess of my code - because of other factors not detailed here - but nothing that an hour or two of re-factoring wont sort out.

like image 429
Noel Walters Avatar asked Mar 12 '09 10:03

Noel Walters


1 Answers

In your example you have defined in Item model relationship as has_many for collection_items and collections the generated association method is collection_items and collections respectively both of them returns an array so the way you are trying to access here is wrong. this is primarily case of mant to many relationship. just check this Asscociation Documentation for further reference.

like image 80
serioys sam Avatar answered Nov 05 '22 02:11

serioys sam