aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation
diff options
context:
space:
mode:
authorAndrew White <andyw@pixeltrix.co.uk>2010-04-04 17:34:23 +0100
committerAndrew White <andyw@pixeltrix.co.uk>2010-04-04 17:34:23 +0100
commit00884a59013a658082dab41da5ff41add31b8c43 (patch)
tree666b862b08b04c7a3727ee22b2cd1a2561af4e52 /activerecord/lib/active_record/relation
parent48b2451142355b22de5f8130b3debdd4e53e2ba2 (diff)
parent7d7e0627a0490b6b4ddb0ee5429264ccd46f1245 (diff)
downloadrails-00884a59013a658082dab41da5ff41add31b8c43.tar.gz
rails-00884a59013a658082dab41da5ff41add31b8c43.tar.bz2
rails-00884a59013a658082dab41da5ff41add31b8c43.zip
Merge branch 'master' of github.com:lifo/docrails
Diffstat (limited to 'activerecord/lib/active_record/relation')
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb20
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder.rb6
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb25
-rw-r--r--activerecord/lib/active_record/relation/spawn_methods.rb15
4 files changed, 52 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 37aaac0894..a26f1c0ac8 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -106,13 +106,29 @@ module ActiveRecord
# A convenience wrapper for <tt>find(:first, *args)</tt>. You can pass in all the
# same arguments to this method as you can to <tt>find(:first)</tt>.
def first(*args)
- args.any? ? apply_finder_options(args.first).first : find_first
+ if args.any?
+ if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash))
+ to_a.first(*args)
+ else
+ apply_finder_options(args.first).first
+ end
+ else
+ find_first
+ end
end
# A convenience wrapper for <tt>find(:last, *args)</tt>. You can pass in all the
# same arguments to this method as you can to <tt>find(:last)</tt>.
def last(*args)
- args.any? ? apply_finder_options(args.first).last : find_last
+ if args.any?
+ if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash))
+ to_a.last(*args)
+ else
+ apply_finder_options(args.first).last
+ end
+ else
+ find_last
+ end
end
# A convenience wrapper for <tt>find(:all, *args)</tt>. You can pass in all the
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index 711df16bf1..d0efa2189d 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -20,10 +20,12 @@ module ActiveRecord
table = Arel::Table.new(table_name, :engine => @engine)
end
- attribute = table[column]
+ unless attribute = table[column]
+ raise StatementInvalid, "No attribute named `#{column}` exists for table `#{table.name}`"
+ end
case value
- when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope
+ when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Relation
values = value.to_a
attribute.in(values)
when Range
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 a17de1bdbb..8fdd64afcc 100644
--- a/activerecord/lib/active_record/relation/spawn_methods.rb
+++ b/activerecord/lib/active_record/relation/spawn_methods.rb
@@ -6,10 +6,9 @@ module ActiveRecord
merged_relation = clone
return merged_relation unless r
- (ActiveRecord::Relation::ASSOCIATION_METHODS + ActiveRecord::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
+ (Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).reject {|m| [:joins, :where].include?(m)}.each do |method|
+ value = r.send(:"#{method}_values")
+ merged_relation.send(:"#{method}_values=", value) if value.present?
end
merged_relation = merged_relation.joins(r.joins_values)
@@ -26,7 +25,7 @@ module ActiveRecord
merged_relation.where_values = merged_wheres
- ActiveRecord::Relation::SINGLE_VALUE_METHODS.reject {|m| m == :lock}.each do |method|
+ Relation::SINGLE_VALUE_METHODS.reject {|m| m == :lock}.each do |method|
unless (value = r.send(:"#{method}_value")).nil?
merged_relation.send(:"#{method}_value=", value)
end
@@ -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