Skip to content

Instantly share code, notes, and snippets.

@moro
Created February 25, 2009 09:33
Show Gist options
  • Save moro/70104 to your computer and use it in GitHub Desktop.
Save moro/70104 to your computer and use it in GitHub Desktop.
From 11de51c1dce437ecee39660fcceb4bfece6c6d7c Mon Sep 17 00:00:00 2001
From: moro <[email protected]>
Date: Wed, 25 Feb 2009 18:30:21 +0900
Subject: [PATCH] dynamic scope should also be available from method chain.
---
activerecord/lib/active_record/base.rb | 11 +----------
.../lib/active_record/dynamic_scope_match.rb | 13 +++++++++++++
activerecord/lib/active_record/named_scope.rb | 5 +++++
3 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 55ab1fa..21e7571 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1950,16 +1950,7 @@ module ActiveRecord #:nodoc:
attribute_names = match.attribute_names
super unless all_attributes_exists?(attribute_names)
if match.scope?
- self.class_eval %{
- def self.#{method_id}(*args) # def self.scoped_by_user_name_and_password(*args)
- options = args.extract_options! # options = args.extract_options!
- attributes = construct_attributes_from_arguments( # attributes = construct_attributes_from_arguments(
- [:#{attribute_names.join(',:')}], args # [:user_name, :password], args
- ) # )
- #
- scoped(:conditions => attributes) # scoped(:conditions => attributes)
- end # end
- }, __FILE__, __LINE__
+ match.build(method_id, self)
send(method_id, *arguments)
end
else
diff --git a/activerecord/lib/active_record/dynamic_scope_match.rb b/activerecord/lib/active_record/dynamic_scope_match.rb
index f796ba6..ab1c30f 100644
--- a/activerecord/lib/active_record/dynamic_scope_match.rb
+++ b/activerecord/lib/active_record/dynamic_scope_match.rb
@@ -21,5 +21,18 @@ module ActiveRecord
def scope?
[email protected]?
end
+
+ def all_attributes_available?
+ all_attributes_exists?(attribute_names)
+ end
+
+ def build(method_id, parent)
+ parent.named_scope method_id, proc{|*args|
+ attributes = parent.send(:construct_attributes_from_arguments,
+ attribute_names.map(&:to_sym), args
+ )
+ {:conditions => attributes}
+ }
+ end
end
end
diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb
index 989b2a1..c2fa7e8 100644
--- a/activerecord/lib/active_record/named_scope.rb
+++ b/activerecord/lib/active_record/named_scope.rb
@@ -165,6 +165,11 @@ module ActiveRecord
def method_missing(method, *args, &block)
if scopes.include?(method)
scopes[method].call(self, *args)
+ elsif match = DynamicScopeMatch.match(method)
+ attribute_names = match.attribute_names
+ super unless all_attributes_exists?(attribute_names) && match.scope?
+ match.build(method, self)
+ send(method, *args)
else
with_scope :find => proxy_options, :create => proxy_options[:conditions].is_a?(Hash) ? proxy_options[:conditions] : {} do
method = :new if method == :build
--
1.6.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment