Named Scopes with Joins and Default Block Arguments
Posted in Code, Ruby on Rails
Today I was fiddling with some code to get particular types of payments that are due on particular days and I ran across a couple of things I don’t want to solve again.
Firstly, the problem of being able to have default arguments to a block in ruby. It’s solved nicely in Ruby 1.9 but we’re using 1.8.x on our boxes at the moment. The work around is incredibly simple though and goes something like this :
lambda { |*args|
date = (args[0] || Date.today)
.. remaining code ..
}
That’s all there is to it really. You could go the whole hog with hashed attributes and so on but I think it starts to get a bit smelly if your anonymous functions are taking more than one argument.
The other issue I had was whether a named scope can include a join, and it can.
named_scope :credit_card, { :joins => :subscription, :conditions => "subscriptions.method = 'credit_card'" }
You can hash it all out if you want to, though if it’s all about readability I find the above to be more suitable. However this will also work :
... :conditions { :payment_plans => { :payment_method => "credit_card" } }
The coolest thing about all of this though (and I feel I’m very late to the party here) is that I now get to do things like :
Payment.credit_card.due_on(Date.today)
# or
Payment.credit_card.due_on
# or
Payment.due_on(Date.today + 1.month)
In the above I had just used the default argument to the due_on named scope to be today’s date.
I mean, I’d seen a bunch of tutorials on named scopes and how they worked but hadn’t found a use case in my work. I think it’s finally twigged for me though and will be making use of them a bit more in the future.
Pingback: Tweets that mention Named Scopes with Joins and Default Block Arguments ยป Transcending Frontiers -- Topsy.com