25

I've got a named scope like this:

named_scope :by_items, lambda |*items| {
  :joins => :items,
  :conditions => ["items.id in (?)", items.map(&::id)]
}

What's the *item mean? When I call it with Item.find(:first, ...) it works fine. If I try to call using a collection, Item.find(:all, ...) it fails.

From a different SO question, I know the signature is supposed to be:

Order.by_items(item0, item1, ...)

So, my question really is, how do I turn an Array into a comma separated argument list?

UPDATE0

From Martin Fowler I've learned:

(Using a "*" in the argument list helps in working with variable arguments in ruby. In the argument list *disks indicates a vararg. I can then refer to all the disks passed in as an array named "disks". If I call another function with "*disks" the elements of the disks array are passed in as separate arguments.)

UPDATE1

More on the "splat" operator.

eebbesen
  • 5,070
  • 8
  • 48
  • 70
Terry G Lorber
  • 2,932
  • 2
  • 23
  • 33

1 Answers1

25

*items means that the function accepts variable number of arguments. In other words, if you call it like this:

Order.by_items(item0, item1, item2)

the variable items inside the named scope lambda function will be an array with 3 items.

To answer your real question, you should call it like this:

Order.by_items(*Item.find(:all, ...))
eebbesen
  • 5,070
  • 8
  • 48
  • 70
stask
  • 866
  • 8
  • 5