Has_many :through problem


#1

This may be a stupid question but I seriously can not find what’s
wrong.
Using Rails 2.3 and Ruby 1.8.7 I have:

class Category < ActiveRecord::Base
has_many :categories_users
has_many :users, :through => :categories_users
%I skip other things here
end

class User < ActiveRecord::Base
has_many :categories_users
has_many :categories, :through => :categories_users
end

class CategoryUser < ActiveRecord::Base
validates_presence_of :category_id, :user_id
belongs_to :category
belongs_to :user
end

and the migration was:

def self.up
drop_table :categories_users
create_table :categories_users do |t|
t.integer :category_id, :user_id
t.timestamps
end
end

I added the timestamps out of desperation, dont think they are
needed.
I really can not see what’s wrong with this set up but:

$ script/console
Loading development environment (Rails 2.3.2)

a =Category.new
/home/jordi/sources/estudio/app/models/category.rb:60: warning: don’t
put space before argument parentheses
=> #<Category id: nil, name: nil, created_at: nil, updated_at: nil,
public: false, created_by: 1>

a.users
NameError: uninitialized constant Category::CategoriesUser
from /home/jordi/.gem/ruby/1.8/gems/activesupport-2.3.2/lib/
active_support/dependencies.rb:105:in const_missing' from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/ active_record/base.rb:2204:incompute_type’
from /home/jordi/.gem/ruby/1.8/gems/activesupport-2.3.2/lib/
active_support/core_ext/kernel/reporting.rb:11:in silence_warnings' from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/ active_record/base.rb:2200:incompute_type’
from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/
active_record/reflection.rb:156:in send' from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/ active_record/reflection.rb:156:inklass’
from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/
active_record/reflection.rb:257:in source_reflection' from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/ active_record/reflection.rb:257:incollect’
from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/
active_record/reflection.rb:257:in source_reflection' from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/ active_record/reflection.rb:288:incheck_validity!’
from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/
active_record/associations/has_many_through_association.rb:5:in
initialize' from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/ active_record/associations.rb:1277:innew’
from /home/jordi/.gem/ruby/1.8/gems/activerecord-2.3.2/lib/
active_record/associations.rb:1277:in `users’
from (irb):2

I have being like 2 days trying to solve this, I am sure is some
evident and stupid thing. Any hint will be very welcomed.


#2

Indeed that was the problem. Thank you very much.


#3

On Apr 24, 5:54 am, jordi polo removed_email_address@domain.invalid wrote:

This may be a stupid question but I seriously can not find what’s
wrong.
Using Rails 2.3 and Ruby 1.8.7 I have:

class Category < ActiveRecord::Base
has_many :categories_users

rails will singularise this and try and look for a class caller
CategoriesUser (as you can tell from the error message)

class CategoryUser < ActiveRecord::Base

but your class is called CategoryUser.

Fred


#4

Hi Andrew,

could you please try this -
class Bookmark
has_many :bookmarks_tags
has_many :tags, :through => :bookmarks_tags
.

class BookmarksTag
belongs_to :tag
belongs_to :bookmark

Then @bookmark.tags should work.

Thanks


#5

Hi Manasi,

This worked. Thank you!

Another thing I found I had to do was rename BookmarksTag.rb to
bookmarks_tag.rb. As a Java programmer who is just starting in ruby I
am still coming to grips with the ruby naming conventions.

Your help was much appreciated. Thank you again!

Andrew.

Manasi V1 wrote:

Hi Andrew,

could you please try this -
class Bookmark
has_many :bookmarks_tags
has_many :tags, :through => :bookmarks_tags
.

class BookmarksTag
belongs_to :tag
belongs_to :bookmark

Then @bookmark.tags should work.

Thanks


#6

I have what I thought was a similar problem, but I am not sure what’s
going wrong.

Here’s my model:

class Bookmark < ActiveRecord::Base
has_many :tags, :through => :bookmarks_tags
end

(in file app/models/bookmark.rb)

class Tag < ActiveRecord::Base
has_many_and_belongs_to_many :bookmarks, :through => :bookmarks_tags
end

(in file app/models/tag.rb)

class BookmarksTag < ActiveRecord::Base
belongs_to :bookmark
belongs_to :tag
end

(in file app/models/BookmarksTag.rb)

My database looks like this:

CREATE TABLE bookmarks (
id int(11) NOT NULL auto_increment,
name varchar(255) default NULL,
url varchar(255) default NULL,
created_at datetime default NULL,
updated_at datetime default NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ;



– Table structure for table bookmarks_tags

CREATE TABLE bookmarks_tags (
bookmark_id int(11) default NULL,
tag_id int(11) default NULL,
created_at datetime default NULL,
updated_at datetime default NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;



– Table structure for table schema_migrations

CREATE TABLE schema_migrations (
version varchar(255) NOT NULL,
UNIQUE KEY unique_schema_migrations (version)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;



– Table structure for table tags

CREATE TABLE tags (
id int(11) NOT NULL auto_increment,
tagword varchar(255) default NULL,
created_at datetime default NULL,
updated_at datetime default NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

I’m getting this error in my “show” view:

Could not find the association :bookmarks_tags in model Bookmark

Extracted source (around line #13):

10:
11:


12: Tags:
13: <% for tag in @bookmark.tags %>
14: <%= tag.tagword %>
15: <% end %>
16:

If I change bookmark.rb as follows it works, but I would like to learn
what I’ve done wrong for future reference.

class Bookmark < ActiveRecord::Base
has_and_belongs_to_many :tags
end

Any advice would be greatly appreciated.

Regards,
Andrew.