Syntax for calling the has_many class methods

I have a simple Active Record model:

class Order < ActiveRecord::Base   has_many :line_items   def add_line_items_from_cart(cart)     cart.items.each do |item|       li = LineItem.from_cart_item(item)       line_items << li     end   end end

This syntax works fine: line_items << li

This also works: self.line_items << li

But this syntax fails with an error (undefined method `line_items' for Order:Class): Order.line_items << li

Why the error?

Thanks, Jeff

I think because you're trying to call something on the Order /class/, rather than on an instance OF an Order.

#line_items is an instance methods. You can’t call them on a Class because there is no link between the models. Try to think of it through the resulting SQL queries.

self.line_items – find all line_items with a order_id of self.id

You have to think of what ‘Order.line_items << li’ means. You can’t do Order.line_items because that would be like saying “find all line_items with order_id of Class.id” which is obviously wrong. Line_items are linked to Orders and so you need to have an order to find line_items.

Just keep in mind that all method calls on ActiveRecord objects are in fact queries to the database (or cached queries).

Hope that helped.

Jason

I get it, thanks. I misunderstood the API documentation. It explains that has_many, et al are class methods. Then it uses a diagram syntax like this to describe the methods that has_many creates:

Firm#clients<<

Class#method is a syntax used to illustrate class methods in the PickAxe book. So I assumed clients<< was a class method, when in fact it is an instance method.

Thanks again, Jeff

Hi --

I get it, thanks. I misunderstood the API documentation. It explains that has_many, et al are class methods. Then it uses a diagram syntax like this to describe the methods that has_many creates:

Firm#clients<<

Class#method is a syntax used to illustrate class methods in the PickAxe book. So I assumed clients<< was a class method, when in fact it is an instance method.

The #method notation is actually for an instance method, like String#split. Class methods are usually indicated like this: ActiveRecord::Base.has_many.

But if the class whose instance method it is is Class, you'd get Class#method.... So, for example, it's correct to refer to Class#new, since new is an instance method of class.

David

Thanks David. You're right. The PickAxe does use Class#method to describe an instance method. I'm mentally challenged today!

-- Jeff