Permalink
Browse files

Fixed AR::Relation#where edge case with Hash and other Relation

Example:

  Author.where(posts: { author_id: Author.where(country_id: 1) }).joins(:posts)
  • Loading branch information...
bogdan committed Aug 14, 2014
1 parent 3300fde commit fe67dfbbeea092f0f42e81e4901fe9a949cf9484
@@ -952,9 +952,7 @@ def build_where(opts, other = [])
self.bind_values += bind_values
attributes = @klass.send(:expand_hash_conditions_for_aggregates, tmp_opts)
- attributes.values.grep(ActiveRecord::Relation) do |rel|
- self.bind_values += rel.bind_values
- end
+ add_relations_to_bind_values(attributes)
PredicateBuilder.build_from_hash(klass, attributes, table)
else
@@ -1137,5 +1135,19 @@ def check_if_method_has_arguments!(method_name, args)
raise ArgumentError, "The method .#{method_name}() must contain arguments."
end
end
+
+ # This function is recursive just for better readablity.
+ # #where argument doesn't support more than one level nested hash in real world.
+ def add_relations_to_bind_values(attributes)
+ if attributes.is_a?(Hash)
+ attributes.each_value do |value|
+ if value.is_a?(ActiveRecord::Relation)
+ self.bind_values += value.bind_values
+ else
+ add_relations_to_bind_values(value)
+ end
+ end
+ end
+ end
end
end
@@ -61,6 +61,15 @@ def test_belongs_to_nested_where
assert_equal expected.to_sql, actual.to_sql
end
+ def test_belongs_to_nested_where_with_relation
+ author = authors(:david)
+
+ expected = Author.where(id: author ).joins(:posts)
+ actual = Author.where(posts: { author_id: Author.where(id: author.id) }).joins(:posts)
+
+ assert_equal expected.to_a, actual.to_a
+ end
+
def test_polymorphic_shallow_where
treasure = Treasure.new
treasure.id = 1

0 comments on commit fe67dfb

Please sign in to comment.