Forum: Ruby on Rails has_many :through associated object ids assignment error

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
740d332f3fd021646add1ab5f8b4dea2?d=identicon&s=25 Bas van Westing (Guest)
on 2007-04-03 21:35
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
391f9b787cdc12aa2c179713f5103e3a?d=identicon&s=25 Ilan Berci (iberci)
on 2007-04-03 22:20
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.. :)

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.. :)

hope this helps

ilan
740d332f3fd021646add1ab5f8b4dea2?d=identicon&s=25 Bas van Westing (Guest)
on 2007-04-03 23:01
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
This topic is locked and can not be replied to.