mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix .update_all and .delete_all when using a condition on a joined table
in a default_scope. `Model.joins(...).where(condition_on_joined_table).update_all` / `delete_all` worked, but the same operation implemented with a default_scope generated a SQL error because ActiveRecord ignored the join but implemented the where condition anyways.
This commit is contained in:
parent
7738222173
commit
bc4edca7b1
3 changed files with 33 additions and 2 deletions
|
@ -276,7 +276,7 @@ module ActiveRecord
|
|||
stmt.table(table)
|
||||
stmt.key = table[primary_key]
|
||||
|
||||
if joins_values.any?
|
||||
if with_default_scope.joins_values.any?
|
||||
@klass.connection.join_to_update(stmt, arel)
|
||||
else
|
||||
stmt.take(arel.limit)
|
||||
|
@ -401,7 +401,7 @@ module ActiveRecord
|
|||
stmt = Arel::DeleteManager.new(arel.engine)
|
||||
stmt.from(table)
|
||||
|
||||
if joins_values.any?
|
||||
if with_default_scope.joins_values.any?
|
||||
@klass.connection.join_to_delete(stmt, arel, table[primary_key])
|
||||
else
|
||||
stmt.wheres = arel.constraints
|
||||
|
|
|
@ -161,6 +161,28 @@ class RelationScopingTest < ActiveRecord::TestCase
|
|||
|
||||
assert !Developer.all.where_values.include?("name = 'Jamis'")
|
||||
end
|
||||
|
||||
def test_default_scope_filters_on_joins
|
||||
assert_equal 1, DeveloperFilteredOnJoins.all.count
|
||||
assert_equal DeveloperFilteredOnJoins.all.first, developers(:david).becomes(DeveloperFilteredOnJoins)
|
||||
end
|
||||
|
||||
def test_update_all_default_scope_filters_on_joins
|
||||
DeveloperFilteredOnJoins.update_all(:salary => 65000)
|
||||
assert_equal 65000, Developer.find(developers(:david).id).salary
|
||||
|
||||
# has not changed jamis
|
||||
assert_not_equal 65000, Developer.find(developers(:jamis).id).salary
|
||||
end
|
||||
|
||||
def test_delete_all_default_scope_filters_on_joins
|
||||
assert_not_equal [], DeveloperFilteredOnJoins.all
|
||||
|
||||
DeveloperFilteredOnJoins.delete_all()
|
||||
|
||||
assert_equal [], DeveloperFilteredOnJoins.all
|
||||
assert_not_equal [], Developer.all
|
||||
end
|
||||
end
|
||||
|
||||
class NestedRelationScopingTest < ActiveRecord::TestCase
|
||||
|
|
|
@ -101,6 +101,15 @@ class DeveloperWithIncludes < ActiveRecord::Base
|
|||
default_scope { includes(:audit_logs) }
|
||||
end
|
||||
|
||||
class DeveloperFilteredOnJoins < ActiveRecord::Base
|
||||
self.table_name = 'developers'
|
||||
has_and_belongs_to_many :projects, -> { order('projects.id') }, :foreign_key => 'developer_id', :join_table => 'developers_projects'
|
||||
|
||||
def self.default_scope
|
||||
joins(:projects).where(:projects => { :name => 'Active Controller' })
|
||||
end
|
||||
end
|
||||
|
||||
class DeveloperOrderedBySalary < ActiveRecord::Base
|
||||
self.table_name = 'developers'
|
||||
default_scope { order('salary DESC') }
|
||||
|
|
Loading…
Reference in a new issue