Forum: Ruby on Rails has_many :through problem

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.
jordi polo (Guest)
on 2009-04-24 11:43
(Received via mailing list)
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:in `compute_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:in `compute_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:in `klass'
        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:in `collect'
        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:in `check_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:in `new'
        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.
Frederick C. (Guest)
on 2009-04-24 11:44
(Received via mailing list)
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
jordi polo (Guest)
on 2009-04-24 11:53
(Received via mailing list)
Indeed that was the problem. Thank you very much.
Andrew M. (Guest)
on 2009-05-20 06:25
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: <p>
12:   <b>Tags:</b>
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.
Manasi V. (Guest)
on 2009-05-21 22:48
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
Andrew M. (Guest)
on 2009-05-24 15:44
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
This topic is locked and can not be replied to.