Support :limit on update_all so that has_many with :limit can be safely updated
Signed-off-by: Michael Koziarski <michael@koziarski.com>
This commit is contained in:
parent
14d1560e85
commit
7c9851dbb6
20
activerecord/lib/active_record/base.rb
Normal file → Executable file
20
activerecord/lib/active_record/base.rb
Normal file → Executable file
@ -769,10 +769,24 @@ def destroy(id)
|
||||
# :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
|
||||
|
||||
|
@ -153,6 +153,10 @@ def case_sensitive_equality_operator
|
||||
"="
|
||||
end
|
||||
|
||||
def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
|
||||
"WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{quoted_table_name} #{where_sql})"
|
||||
end
|
||||
|
||||
protected
|
||||
# Returns an array of record hashes with the column names as keys and
|
||||
# column values as values.
|
||||
|
@ -523,6 +523,10 @@ def case_sensitive_equality_operator
|
||||
"= BINARY"
|
||||
end
|
||||
|
||||
def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
|
||||
where_sql
|
||||
end
|
||||
|
||||
private
|
||||
def connect
|
||||
@connection.reconnect = true if @connection.respond_to?(:reconnect=)
|
||||
|
@ -76,7 +76,7 @@ class TopicWithProtectedContentAndAccessibleAuthorName < ActiveRecord::Base
|
||||
end
|
||||
|
||||
class BasicsTest < ActiveRecord::TestCase
|
||||
fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories
|
||||
fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts
|
||||
|
||||
def test_table_exists
|
||||
assert !NonExistentTable.table_exists?
|
||||
@ -664,10 +664,21 @@ def test_update_all_with_order_and_limit
|
||||
end
|
||||
end
|
||||
|
||||
def test_update_all_ignores_order_limit_from_association
|
||||
author = Author.find(1)
|
||||
def test_update_all_ignores_order_without_limit_from_association
|
||||
author = authors(:david)
|
||||
assert_nothing_raised do
|
||||
assert_equal author.posts_with_comments_and_categories.length, author.posts_with_comments_and_categories.update_all("body = 'bulk update!'")
|
||||
assert_equal author.posts_with_comments_and_categories.length, author.posts_with_comments_and_categories.update_all([ "body = ?", "bulk update!" ])
|
||||
end
|
||||
end
|
||||
|
||||
def test_update_all_with_order_and_limit_updates_subset_only
|
||||
author = authors(:david)
|
||||
assert_nothing_raised do
|
||||
assert_equal 1, author.posts_sorted_by_id_limited.size
|
||||
assert_equal 2, author.posts_sorted_by_id_limited.find(:all, :limit => 2).size
|
||||
assert_equal 1, author.posts_sorted_by_id_limited.update_all([ "body = ?", "bulk update!" ])
|
||||
assert_equal "bulk update!", posts(:welcome).body
|
||||
assert_not_equal "bulk update!", posts(:thinking).body
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -2,6 +2,7 @@ class Author < ActiveRecord::Base
|
||||
has_many :posts, :accessible => true
|
||||
has_many :posts_with_comments, :include => :comments, :class_name => "Post"
|
||||
has_many :posts_with_comments_sorted_by_comment_id, :include => :comments, :class_name => "Post", :order => 'comments.id'
|
||||
has_many :posts_sorted_by_id_limited, :class_name => "Post", :order => 'posts.id', :limit => 1
|
||||
has_many :posts_with_categories, :include => :categories, :class_name => "Post"
|
||||
has_many :posts_with_comments_and_categories, :include => [ :comments, :categories ], :order => "posts.id", :class_name => "Post"
|
||||
has_many :posts_containing_the_letter_a, :class_name => "Post"
|
||||
|
Loading…
Reference in New Issue
Block a user