OOP Question

On Rails using associations you can have something like this:

Category.find(1).articles #=> Array of Article objects

So if that returns an array how is something like this possible?

Category.find(1).articles.find_by_author_id(1)

Instead of calling the method "find_by_author_id" from the Article
class shouldn't Ruby have called it from the Array class?

Thanks in advance

toulax wrote:

On Rails using associations you can have something like this:

Category.find(1).articles #=> Array of Article objects

So if that returns an array how is something like this possible?

Category.find(1).articles.find_by_author_id(1)

Instead of calling the method "find_by_author_id" from the Article
class shouldn't Ruby have called it from the Array class?

Ruby is better OO than OO.

articles is both an Array and a live link between a Category and the
Article class. So the Article class can do a method_missing() to
concoct a find_by_whatever_column, and the articles link bequeaths to
it a filter restricting the results to the current Category.

Good luck finding stuff like this in all the OO books out there...

Philip,

Thanks, I figured about the method_missing part, but how does Ruby
know when to use Array and when to use Article in this case. Better
yet, how could I reproduce this behavior?

Thanks

toulax wrote:

Thanks, I figured about the method_missing part, but how does Ruby
know when to use Array and when to use Article in this case.

They are both. The capacities of Array and Article are merged together.

Try this:

def what?(anObject, aint = self)
  p anObject.class.name
  puts (anObject.public_methods - aint.public_methods).sort
end

Call what?cat.articles, and it will probably report that articles is an Array. Then call what?cat.articles, [], and it might report a bunch of extra methods that articles added to the array.

Better yet, how could I reproduce this behavior?

Look up Ruby metaprogramming, including the chapter called IIRC "write code with code" in the book /Rails Recipes/.

Hi --

On Rails using associations you can have something like this:

Category.find(1).articles #=> Array of Article objects

So if that returns an array how is something like this possible?

Category.find(1).articles.find_by_author_id(1)

Instead of calling the method "find_by_author_id" from the Article
class shouldn't Ruby have called it from the Array class?

You don't call methods from a class; you send messages to objects, and
the object looks for the method in the classes and modules in its
lookup path. That sounds like splitting hairs, but it's an important
conceptual and technical difference.

You've got an object that reports its class as Array -- but in Ruby,
the class of an object does not definitively tell you what the object
can do. In this particular case, the object has a method_missing hook
that intercepts the message "find_by_author_id" and does something
useful with it.

So that articles collection is an Array, as indicated by its class,
but the main thing is that it's an object to which you can send
certain messages and get a result. It doesn't much matter what it says
its class is, since class membership doesn't govern an object's
behavior.

David

I see now that the method is really being called on the Array, but it
still seems quite hard to grasp so I'll have to look further into
metaprogramming.

Thanks everyone