I want to sort my Person model objects based on a complicated criterion that can't be summarized in a single query - and so in a named scope. Right now I use a class method like:
def Person.very_complicated_sorting
Person.all.sort { |x,y| x.bunch_of_calculations <=> y.bunch_of_calculations }
end
Is there a way to make this chainable? E.g.
Person.tallest.very_complicate_sorting.youngest
where tallest and youngest are two named scopes.
This isn't possible unfortunately.
The way named scopes work is by "lazily" building up a combined set of SQL parameters, which aren't evaluated until you actually try to do something with them. So for example the following chain of named scopes:
will not cause any database query to be run, it actually causes an
ActiveRecord::NamedScopeobject to be stored in thepeoplevariable. Only when you access or iterate through that object is the SQL run and the objects loaded.Your problem is that your sorting method isn't being expressed in SQL, it's a set of Ruby conditions. When Rails gets to your
sort_byit has to go and fetch and instantiate thePersonobjects so that it can run your condition on them. After it's done that you have anArrayof objects and not aNamedScopeobject any more.