On Tue, Oct 19, 2010 at 04:16:33PM -0500, Tim Morgan wrote: > Sure! > > Here is the updated patch: > https://rails.lighthouseapp.com/projects/8994/tickets/1812/a/727956/allow-default_scope-to-accept-a-proc2.patch
Thanks! I've applied it and extended it a little bit so that
default_scope will take any object that responds to "call".
I'll show some code, then try to explain the benefits. This is now possible:
class AuthorFilter < Struct.new(:klass, :author_id)
def call
klass.where(:author_id => author_id)
end
end
class AmazingPost < ActiveRecord::Base
self.table_name = 'posts'
default_scope AuthorFilter.new(self, 2)
end
The Object form does not need to save binding like the lambda form does. This
can lead to less memory usage and help curb "leaking objects".
Because we can use objects, it allows our default scopes to contain more
logic: we can actually break up functionality to other methods. For
example:
class AuthorFilter < Struct.new(:klass, :some_value)
def calculate_id
... do som complex logic to figure out the id ...
end
def call
klass.where(:author_id => calculate_id)
end
end
We can even use modules or subclasses to extend our logic. For example:
module BodyFilter
def call
super.where(:body => 'hello')
end
end
class AuthorFilter < Struct.new(:klass, :author_id)
def call
klass.where(:author_id => author_id)
end
end
class AmazingPost < ActiveRecord::Base
self.table_name = 'posts'
# Produces: WHERE author_id = 2 AND body = 'hello'
default_scope AuthorFilter.new(self, 2).extend(BodyFilter)
end
Finally, we can more easily test any complex logic we need in this
filter:
class FilterTest < Test::Unit::TestCase
class DreamCatcher
attr_reader :wheres
def initialize; @wheres = []; end
def where(arg); @wheres << arg; end
end
def test_appropriate_where_clause
dc = DreamCatcher.new
AuthorFilter.new(dc, 2).call
assert_equal([{:author_id => 2}], dc.wheres)
end
end
I'd like to see the rest of our scope methods to allow arbitrary objects
that respond to `call` for the above reasons. :-)
--
Aaron Patterson
http://tenderlovemaking.com/
pgptfYFcnRkWr.pgp
Description: PGP signature
