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

Improve error message for #or when it is structurally incompatible

When you are using scopes and you chaining these scopes it is hard to
know which are the values that are incompatible. This way you can read
the message and know for which values you need to look for.

[Herminio Torres]
This commit is contained in:
Rafael Mendonça França 2016-01-13 01:13:18 -02:00
parent 7b7b12f598
commit f466cd7fc4
2 changed files with 11 additions and 7 deletions

View file

@ -659,8 +659,10 @@ module ActiveRecord
end
def or!(other) # :nodoc:
unless structurally_compatible_for_or?(other)
raise ArgumentError, 'Relation passed to #or must be structurally compatible'
incompatible_values = structurally_incompatible_values_for_or(other)
unless incompatible_values.empty?
raise ArgumentError, "Relation passed to #or must be structurally compatible. Incompatible values: #{incompatible_values}"
end
self.where_clause = self.where_clause.or(other.where_clause)
@ -1189,10 +1191,10 @@ module ActiveRecord
end
end
def structurally_compatible_for_or?(other)
Relation::SINGLE_VALUE_METHODS.all? { |m| send("#{m}_value") == other.send("#{m}_value") } &&
(Relation::MULTI_VALUE_METHODS - [:extending]).all? { |m| send("#{m}_values") == other.send("#{m}_values") } &&
(Relation::CLAUSE_METHODS - [:having, :where]).all? { |m| send("#{m}_clause") == other.send("#{m}_clause") }
def structurally_incompatible_values_for_or(other)
Relation::SINGLE_VALUE_METHODS.reject { |m| send("#{m}_value") == other.send("#{m}_value") } +
(Relation::MULTI_VALUE_METHODS - [:extending]).reject { |m| send("#{m}_values") == other.send("#{m}_values") } +
(Relation::CLAUSE_METHODS - [:having, :where]).reject { |m| send("#{m}_clause") == other.send("#{m}_clause") }
end
def new_where_clause

View file

@ -52,9 +52,11 @@ module ActiveRecord
end
def test_or_with_incompatible_relations
assert_raises ArgumentError do
error = assert_raises ArgumentError do
Post.order('body asc').where('id = 1').or(Post.order('id desc').where(:id => [2, 3])).to_a
end
assert_equal "Relation passed to #or must be structurally compatible. Incompatible values: [:order]", error.message
end
def test_or_when_grouping