Question

In my Rails 3.2.8 app I have some named scopes I would like to chain together in some circumstances.

So, for example, I have these two scopes:

scope :by_status, lambda { |status| if status == "All" then WorkRequest.all else WorkRequest.find_all_by_status(status) end }
scope :in_date_range, lambda { |start_date, end_date| includes([:person, :pier_module]).where("(status_date >= ?) AND (status_date <= ?)", start_date, end_date) }

I use them separately, but I'd also like to be able to call them together like this:

WorkRequest.by_status("Accepted").in_date_range("2012-01-01", "2012-10-02")

When I try that it complains that in_date_range is not a method of Array.

But I have another scope,

scope :active, includes([:person, :pier_module]).where("status = 'New Request'")

and if I do

WorkRequest.active.in_date_range("2012-01-01", "2012-10-02")

it works! Apparently the active scope returns a Relation, whereas the lambda scopes return Arrays, and so can't be chained.

I'd love to know why the difference between simpler scopes and lambda scopes, how the parameters affect it, and whether there's anything I can do short of writing a combined scope, which I've done.

scope :by_status_in_date_range, lambda { |status, start_date, end_date|  includes([:person, :pier_module]).where("(status = ?) AND (status_date >= ?) AND (status_date <= ?)", status, start_date, end_date) }

Works, but not very DRY (since I need the individual scopes, too) or Rails-ish. Searching here and elsewhere I've seen similar questions but none that seem to apply to this situation, where I'm trying to chain two lambdas with parameters.

Was it helpful?

Solution

That happens because in your scope

scope :by_status, lambda { |status| if status == "All" then WorkRequest.all else WorkRequest.find_all_by_status(status) end }

metods all and find_all_by_status returns Array instead of ActiveRecord::Relation. You should replace it with where for example.

scope :by_status, lambda { |status| where(:status => status) unless status == "All" }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top