1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Allow unscope to work with where.not

Allows you to call #unscope on a relation with negative equality operators,
i.e. Arel::Nodes::NotIn and Arel::Nodes::NotEqual that have been generated
through the use of where.not.
This commit is contained in:
Eric Hankins 2013-10-16 13:39:43 -05:00
parent 7364156391
commit b057765817
3 changed files with 23 additions and 7 deletions

View file

@ -1,3 +1,11 @@
* `ActiveRecord::QueryMethods#unscope` unscopes negative equality
Allows you to call `#unscope` on a relation with negative equality
operators, i.e. `Arel::Nodes::NotIn` and `Arel::Nodes::NotEqual` that have
been generated through the use of `where.not`.
*Eric Hankins*
* Raise an exception when model without primary key calls `.find_with_ids`. * Raise an exception when model without primary key calls `.find_with_ids`.
*Shimpei Makimoto* *Shimpei Makimoto*

View file

@ -856,7 +856,7 @@ module ActiveRecord
where_values.reject! do |rel| where_values.reject! do |rel|
case rel case rel
when Arel::Nodes::In, Arel::Nodes::Equality when Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual
subrelation = (rel.left.kind_of?(Arel::Attributes::Attribute) ? rel.left : rel.right) subrelation = (rel.left.kind_of?(Arel::Attributes::Attribute) ? rel.left : rel.right)
subrelation.name.to_sym == target_value_sym subrelation.name.to_sym == target_value_sym
else else

View file

@ -122,17 +122,25 @@ class DefaultScopingTest < ActiveRecord::TestCase
end end
def test_unscope_with_where_attributes def test_unscope_with_where_attributes
expected = Developer.order('salary DESC').collect { |dev| dev.name } expected = Developer.order('salary DESC').collect(&:name)
received = DeveloperOrderedBySalary.where(name: 'David').unscope(where: :name).collect { |dev| dev.name } received = DeveloperOrderedBySalary.where(name: 'David').unscope(where: :name).collect(&:name)
assert_equal expected, received assert_equal expected, received
expected_2 = Developer.order('salary DESC').collect { |dev| dev.name } expected_2 = Developer.order('salary DESC').collect(&:name)
received_2 = DeveloperOrderedBySalary.select("id").where("name" => "Jamis").unscope({:where => :name}, :select).collect { |dev| dev.name } received_2 = DeveloperOrderedBySalary.select("id").where("name" => "Jamis").unscope({:where => :name}, :select).collect(&:name)
assert_equal expected_2, received_2 assert_equal expected_2, received_2
expected_3 = Developer.order('salary DESC').collect { |dev| dev.name } expected_3 = Developer.order('salary DESC').collect(&:name)
received_3 = DeveloperOrderedBySalary.select("id").where("name" => "Jamis").unscope(:select, :where).collect { |dev| dev.name } received_3 = DeveloperOrderedBySalary.select("id").where("name" => "Jamis").unscope(:select, :where).collect(&:name)
assert_equal expected_3, received_3 assert_equal expected_3, received_3
expected_4 = Developer.order('salary DESC').collect(&:name)
received_4 = DeveloperOrderedBySalary.where.not("name" => "Jamis").unscope(where: :name).collect(&:name)
assert_equal expected_4, received_4
expected_5 = Developer.order('salary DESC').collect(&:name)
received_5 = DeveloperOrderedBySalary.where.not("name" => ["Jamis", "David"]).unscope(where: :name).collect(&:name)
assert_equal expected_5, received_5
end end
def test_unscope_multiple_where_clauses def test_unscope_multiple_where_clauses