1

I have a couple of models

class Product < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

and

class Category < ActiveRecord::Base
  has_and_belongs_to_many :products
end

Now why can't i say

prod = Product.new
prod.categories << Category.new

Why does has_and_belongs_to_many adds class methods like Product#categories<< while it should have added instance methods ?

How can i make use of these class methods to set associations ?

nik7
  • 3,018
  • 6
  • 25
  • 36
  • That is an instance method. Why do you think it isn't? – michelpm Jun 10 '13 at 03:08
  • as per this http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_and_belongs_to_many – nik7 Jun 10 '13 at 03:10
  • Are you getting an error message when you attempt to access them as instance associations? – lurker Jun 10 '13 at 03:12
  • yes, undefined method `categories' for # – nik7 Jun 10 '13 at 03:12
  • That is fishy, why is it looking on ActiveRecord::Relation and not in your class? That class is used for queries. If you type this two lines of code you gave us on rails console, does it show this error? – michelpm Jun 10 '13 at 03:22
  • i am using this in a rake task, for whatever it worth – nik7 Jun 10 '13 at 03:25
  • But not this code you gave us. I suppose that if you test it on console it works just fine. Give us the code that you create or retrieve the Product instance then I can say what is wrong with it. – michelpm Jun 10 '13 at 03:27
  • This is what the error should look like: **undefined method `categories' for #** if your association didn't exist. – michelpm Jun 10 '13 at 03:28
  • http://pastebin.com/hgnT5fHD – nik7 Jun 10 '13 at 03:28
  • Did you create and run a Rails migration to add the corresponding attributes to your tables? – lurker Jun 10 '13 at 03:38

2 Answers2

2

With the error and code you gave me, that is what you are probably missing:

prod = Product.new              # This is a Product instance
prod.categories << Category.new # This works

prod = Product.where(name:'x')  # This returns a query (ActiveRecord::Relation) 
prod.categories << Category.new # This doesn't work

prod = Product.where(name:'x').first  # This is a Product instance
prod.categories << Category.new       # This works
michelpm
  • 1,795
  • 2
  • 18
  • 31
0

When creating a new object (let's say Product), you can use the .build method to fill out those associations and call save!

EDIT: here is a good read

Community
  • 1
  • 1
kushyar
  • 1,191
  • 1
  • 6
  • 10
  • all instances of Product need to have access to the categories means it should be an instance method, but the truth is it is actually a class method. Please re-read the question :) – nik7 Jun 10 '13 at 03:09