Has_many :through associated object ids assignment error


#1

Hi,

I have the following situation:

class Article < ActiveRecord::Base
has_many :readings
has_many :users, :through => :readings
end

class Reading < ActiveRecord::Base
belongs_to :article
belongs_to :user
end

Now what I’m trying to do is:

article = Article.new
article.save!

user ids 1,2,3 exist in database, as does the article

article.user_ids = [ 1, 2, 3 ]

But I get the following error:

“undefined method `user_ids=’ for #Article:0x4aea69c

Why isn’t the “user_ids=” method created?

Thanks,
Bas


#2

Bas van Westing wrote:

class Article < ActiveRecord::Base
has_many :readings
has_many :users, :through => :readings
end

class Reading < ActiveRecord::Base
belongs_to :article
belongs_to :user
end

Seems to me this is not the model you are seeking… perhaps this one:
class Article < ActiveRecord::Base
has_many :readings
end

class User < ActiveRecord::Base
has_many :readings
end

class Reading < ActiveRecord::Base
belongs_to :user # like a regular join table… but there are
benefits to making it a first class model
belongs_to :article
end

This makes sense to me, an article can be read by many users and a user
can read many articles making either a join table or a join model
necccessary…

if you just prefer the link table approach, you can go with this:

class Article < ActiveRecord::Base
has_and_belongs_to_many :users, :through=>:readings
end

class User < ActiveRecord::Base
has_and_belongs_to_many :articles, :through=>:readings
end # remember to set the link table “readings” id=>false in the
migration file

Now what I’m trying to do is:

article = Article.new
article.save!

user ids 1,2,3 exist in database, as does the article

article.user_ids = [ 1, 2, 3 ]

But I get the following error:

“undefined method `user_ids=’ for #Article:0x4aea69c

Why isn’t the “user_ids=” method created?

Thanks,
Bas

with the above model approach, you can do

a = Article.create
3.times { a.readings << User.create } # let rails assign the ids… it’s
basically none of your bussiness outside of test cases… :slight_smile:

User.find(:all).count # => 3

or with the link table approach, you can do
a = Article.new
3.times {a.users << User.create}

none of the above code segments have been tested but it’s the general
idea… :slight_smile:

hope this helps

ilan


#3

Thanks Ilan for your reply,

I thought that has_and_belongs_to_many was depreciated (or at least not
a best practice anymore), since in the “Agile Web development with
Rails” book it is not advices to use it anymore.

The ActiveRecord join model is said to be the preferred way of working,
but I still like to use the ‘user_ids=’ assignment which is allowed in
the habtm variant.

In my current application, I just defined the missing method myself, so
I can keep working with the benefits of the habtm approach.

class Article
def user_ids=(array = [])

end
end

This works for me, but I hoped it would be auto-generated for me by
using the “has_many :users, through => :readings” DSL line.

Regards, Bas