Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix .update_all and .delete_all when using a condition on a joined table in a default_scope #8994

Merged
merged 1 commit into from

2 participants

@derekkraan

cc @jonleighton

Here's the first commit from #8473.

@derekkraan derekkraan 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.
bc4edca
@jonleighton jonleighton merged commit 40e7978 into from
@derekkraan derekkraan deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 11, 2013
  1. @derekkraan

    Fix .update_all and .delete_all when using a condition on a joined table

    derekkraan authored
    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 page is out of date. Refresh to see the latest.
View
4 activerecord/lib/active_record/relation.rb
@@ -276,7 +276,7 @@ def update_all(updates)
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 @@ def delete_all(conditions = nil)
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
View
22 activerecord/test/cases/relation_scoping_test.rb
@@ -161,6 +161,28 @@ def test_ensure_that_method_scoping_is_correctly_restored
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
View
9 activerecord/test/models/developer.rb
@@ -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') }
Something went wrong with that request. Please try again.