aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/base.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/base.rb')
-rwxr-xr-xactiverecord/lib/active_record/base.rb23
1 files changed, 19 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 907495a416..fc6d762fcd 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -274,7 +274,7 @@ module ActiveRecord #:nodoc:
# == Dynamic attribute-based finders
#
# Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects by simple queries without turning to SQL. They work by
- # appending the name of an attribute to <tt>find_by_</tt> or <tt>find_all_by_</tt>, so you get finders like <tt>Person.find_by_user_name</tt>,
+ # appending the name of an attribute to <tt>find_by_</tt>, <tt>find_last_by_</tt>, or <tt>find_all_by_</tt>, so you get finders like <tt>Person.find_by_user_name</tt>,
# <tt>Person.find_all_by_last_name</tt>, and <tt>Payment.find_by_transaction_id</tt>. So instead of writing
# <tt>Person.find(:first, :conditions => ["user_name = ?", user_name])</tt>, you just do <tt>Person.find_by_user_name(user_name)</tt>.
# And instead of writing <tt>Person.find(:all, :conditions => ["last_name = ?", last_name])</tt>, you just do <tt>Person.find_all_by_last_name(last_name)</tt>.
@@ -287,6 +287,7 @@ module ActiveRecord #:nodoc:
# It's even possible to use all the additional parameters to find. For example, the full interface for <tt>Payment.find_all_by_amount</tt>
# is actually <tt>Payment.find_all_by_amount(amount, options)</tt>. And the full interface to <tt>Person.find_by_user_name</tt> is
# actually <tt>Person.find_by_user_name(user_name, options)</tt>. So you could call <tt>Payment.find_all_by_amount(50, :order => "created_on")</tt>.
+ # Also you may call <tt>Payment.find_last_by_amount(amount, options)</tt> returning the last record matching that amount and options.
#
# The same dynamic finder style can be used to create the object if it doesn't already exist. This dynamic finder is called with
# <tt>find_or_create_by_</tt> and will return the object if it already exists and otherwise creates it, then returns it. Protected attributes won't be set unless they are given in a block. For example:
@@ -768,10 +769,24 @@ module ActiveRecord #:nodoc:
# :order => 'created_at', :limit => 5 )
def update_all(updates, conditions = nil, options = {})
sql = "UPDATE #{quoted_table_name} SET #{sanitize_sql_for_assignment(updates)} "
+
scope = scope(:find)
- add_conditions!(sql, conditions, scope)
- add_order!(sql, options[:order], nil)
- add_limit!(sql, options, nil)
+
+ select_sql = ""
+ add_conditions!(select_sql, conditions, scope)
+
+ if options.has_key?(:limit) || (scope && scope[:limit])
+ # Only take order from scope if limit is also provided by scope, this
+ # is useful for updating a has_many association with a limit.
+ add_order!(select_sql, options[:order], scope)
+
+ add_limit!(select_sql, options, scope)
+ sql.concat(connection.limited_update_conditions(select_sql, quoted_table_name, connection.quote_column_name(primary_key)))
+ else
+ add_order!(select_sql, options[:order], nil)
+ sql.concat(select_sql)
+ end
+
connection.update(sql, "#{name} Update")
end