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.
Single asterisk as used in function declaration allows variable number of arguments passed from calling environment. Inside the function it behaves as a tuple.
The asterisk is an operator in Python that is commonly known as the multiplication symbol when used between two numbers ( 2 * 3 will produce 6 ) but when it is inserted at the beginning of a variable, such as an iterable, like a list or dictionary, it expands the contents of that variable.
The last parameter of a method may be preceded by an asterisk(*), which is sometimes called the 'splat' operator. This indicates that more parameters may be passed to the function. Those parameters are collected up and an array is created. The asterisk operator may also precede an Array argument in a method call.
Here single asterisk( * ) is also used in *args. It is used to pass a variable number of arguments to a function, it is mostly used to pass a non-key argument and variable-length argument list.
*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, ...))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With