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