aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2010-04-02 17:34:48 +0100
committerPratik Naik <pratiknaik@gmail.com>2010-04-02 17:38:02 +0100
commitb77dd218ce845f01753d02fcbc2605c9a5ee93e1 (patch)
treeea07dbe6965bd31ea7d066e04f7dad0e67e62f31 /activerecord/lib
parentbc7da9b77d6347eeccefa2c735b2f236a08eea57 (diff)
downloadrails-b77dd218ce845f01753d02fcbc2605c9a5ee93e1.tar.gz
rails-b77dd218ce845f01753d02fcbc2605c9a5ee93e1.tar.bz2
rails-b77dd218ce845f01753d02fcbc2605c9a5ee93e1.zip
Add Relation extensions
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/named_scope.rb7
-rw-r--r--activerecord/lib/active_record/relation.rb8
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb25
-rw-r--r--activerecord/lib/active_record/relation/spawn_methods.rb11
4 files changed, 36 insertions, 15 deletions
diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb
index 9abf979cd0..3456332227 100644
--- a/activerecord/lib/active_record/named_scope.rb
+++ b/activerecord/lib/active_record/named_scope.rb
@@ -133,19 +133,16 @@ module ActiveRecord
delegate :scopes, :with_scope, :with_exclusive_scope, :scoped_methods, :scoped, :to => :klass
def self.init(klass, options, &block)
- relation = new(klass, klass.arel_table)
+ relation = new(klass, klass.arel_table, &block)
scope = if options.is_a?(Hash)
- klass.scoped.apply_finder_options(options.except(:extend))
+ klass.scoped.apply_finder_options(options)
else
options ? klass.scoped.merge(options) : klass.scoped
end
relation = relation.merge(scope)
- Array.wrap(options[:extend]).each {|extension| relation.send(:extend, extension) } if options.is_a?(Hash)
- relation.send(:extend, Module.new(&block)) if block_given?
-
relation.current_scoped_methods_when_defined = klass.send(:current_scoped_methods)
relation
end
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 8577ec58f7..dde20532af 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -4,7 +4,7 @@ module ActiveRecord
class Relation
JoinOperation = Struct.new(:relation, :join_class, :on)
ASSOCIATION_METHODS = [:includes, :eager_load, :preload]
- MULTI_VALUE_METHODS = [:select, :group, :order, :joins, :where, :having]
+ MULTI_VALUE_METHODS = [:select, :group, :order, :joins, :where, :having, :extends]
SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :create_with, :from]
include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches
@@ -13,8 +13,9 @@ module ActiveRecord
delegate :insert, :to => :arel
attr_reader :table, :klass
+ attr_accessor :extensions
- def initialize(klass, table)
+ def initialize(klass, table, &block)
@klass, @table = klass, table
@implicit_readonly = nil
@@ -22,6 +23,9 @@ module ActiveRecord
SINGLE_VALUE_METHODS.each {|v| instance_variable_set(:"@#{v}_value", nil)}
(ASSOCIATION_METHODS + MULTI_VALUE_METHODS).each {|v| instance_variable_set(:"@#{v}_values", [])}
+ @extensions = []
+
+ apply_modules(Module.new(&block)) if block_given?
end
def new(*args, &block)
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index e224781016..b5e8b7570a 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -10,8 +10,9 @@ module ActiveRecord
next if [:where, :having].include?(query_method)
class_eval <<-CEVAL
- def #{query_method}(*args)
+ def #{query_method}(*args, &block)
new_relation = clone
+ new_relation.send(:apply_modules, Module.new(&block)) if block_given?
value = Array.wrap(args.flatten).reject {|x| x.blank? }
new_relation.#{query_method}_values += value if value.present?
new_relation
@@ -21,8 +22,9 @@ module ActiveRecord
[:where, :having].each do |query_method|
class_eval <<-CEVAL
- def #{query_method}(*args)
+ def #{query_method}(*args, &block)
new_relation = clone
+ new_relation.send(:apply_modules, Module.new(&block)) if block_given?
value = build_where(*args)
new_relation.#{query_method}_values += [*value] if value.present?
new_relation
@@ -34,8 +36,9 @@ module ActiveRecord
attr_accessor :"#{query_method}_value"
class_eval <<-CEVAL
- def #{query_method}(value = true)
+ def #{query_method}(value = true, &block)
new_relation = clone
+ new_relation.send(:apply_modules, Module.new(&block)) if block_given?
new_relation.#{query_method}_value = value
new_relation
end
@@ -43,8 +46,16 @@ module ActiveRecord
end
end
- def lock(locks = true)
+ def extending(*modules)
+ new_relation = clone
+ new_relation.send :apply_modules, *modules
+ new_relation
+ end
+
+ def lock(locks = true, &block)
relation = clone
+ relation.send(:apply_modules, Module.new(&block)) if block_given?
+
case locks
when String, TrueClass, NilClass
clone.tap {|new_relation| new_relation.lock_value = locks || true }
@@ -191,6 +202,12 @@ module ActiveRecord
private
+ def apply_modules(modules)
+ values = Array.wrap(modules)
+ @extensions += values if values.present?
+ values.each {|extension| extend(extension) }
+ end
+
def reverse_sql_order(order_query)
order_query.to_s.split(/,/).each { |s|
if s.match(/\s(asc|ASC)$/)
diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb
index 63246079cb..8fdd64afcc 100644
--- a/activerecord/lib/active_record/relation/spawn_methods.rb
+++ b/activerecord/lib/active_record/relation/spawn_methods.rb
@@ -7,9 +7,8 @@ module ActiveRecord
return merged_relation unless r
(Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).reject {|m| [:joins, :where].include?(m)}.each do |method|
- unless (value = r.send(:"#{method}_values")).blank?
- merged_relation.send(:"#{method}_values=", value)
- end
+ value = r.send(:"#{method}_values")
+ merged_relation.send(:"#{method}_values=", value) if value.present?
end
merged_relation = merged_relation.joins(r.joins_values)
@@ -34,6 +33,9 @@ module ActiveRecord
merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
+ # Apply scope extension modules
+ merged_relation.send :apply_modules, r.extensions
+
merged_relation
end
@@ -69,7 +71,7 @@ module ActiveRecord
result
end
- VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset,
+ VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset, :extend,
:order, :select, :readonly, :group, :having, :from, :lock ]
def apply_finder_options(options)
@@ -84,6 +86,7 @@ module ActiveRecord
relation = relation.where(options[:conditions]) if options.has_key?(:conditions)
relation = relation.includes(options[:include]) if options.has_key?(:include)
+ relation = relation.extending(options[:extend]) if options.has_key?(:extend)
relation
end