Permalink
Browse files

Use bind instead of instance_exec cause it may be causing memory leak…

…s. Also, provide a simpler and sane implementation for scoped. [#5044 state:resolved]
  • Loading branch information...
1 parent 67e18c5 commit bfbdeeae3080c89a0b27e42d684cbeb6206c6f60 @josevalim josevalim committed Jul 4, 2010
Showing with 10 additions and 9 deletions.
  1. +10 −9 activerecord/lib/active_record/named_scope.rb
@@ -8,17 +8,18 @@ module NamedScope
#
# You can define a scope that applies to all finders using ActiveRecord::Base.default_scope.
def self.included(base)
- base.class_eval do
- extend ClassMethods
- named_scope :scoped, lambda { |scope| scope }
- end
+ base.extend ClassMethods
end
module ClassMethods
def scopes
read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
end
+ def scoped(scope, &block)
+ Scope.new(self, scope, &block)
+ end
+
# Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query,
# such as <tt>:conditions => {:color => :red}, :select => 'shirts.*', :include => :washing_instructions</tt>.
#
@@ -84,22 +85,22 @@ def scopes
# assert_equal expected_options, Shirt.colored('red').proxy_options
def named_scope(name, options = {}, &block)
name = name.to_sym
+
scopes[name] = lambda do |parent_scope, *args|
Scope.new(parent_scope, case options
when Hash
options
when Proc
if self.model_name != parent_scope.model_name
- parent_scope.instance_exec(*args, &options)
+ options.bind(parent_scope).call(*args)
else
options.call(*args)
end
end, &block)
end
- (class << self; self end).instance_eval do
- define_method name do |*args|
- scopes[name].call(self, *args)
- end
+
+ singleton_class.send :define_method, name do |*args|
+ scopes[name].call(self, *args)
end
end
end

0 comments on commit bfbdeea

Please sign in to comment.