From 174c8e0067985a9f5d3f7d01c1a02308bfe66113 Mon Sep 17 00:00:00 2001 From: evazion Date: Sun, 6 Nov 2022 21:08:55 -0600 Subject: [PATCH] Fix #5335: Queries with "ordfav:" and geometry attributes (e.g. "ratio:", "height:") crashes the api/site. Fix `Relation passed to #and must be structurally compatible. Incompatible values: [:joins] (ArgumentError)` exception in `ordfav:evazion ratio:4:3` search. Broken by e849d8f1c. We were effectively doing this: q1 = Post.joins(:favorites, :media_asset).where("favorites.user_id = ?", 52664).order("favorites.id DESC") q2 = Post.joins(:media_asset, :favorites).where("ROUND(media_assets.image_width::numeric / media_assets.image_height::numeric, 2) = 1.33") q3 = q1.and(q2) This failed because Rails didn't like the fact that the joins were in a different order when the queries were `and`-ed together. --- app/logical/post_query_builder.rb | 4 ++-- test/unit/post_query_builder_test.rb | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index c66d40cd6..ce5b463d1 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -244,12 +244,12 @@ class PostQueryBuilder in :and joins = children.flat_map(&:joins_values) orders = children.flat_map(&:order_values) - nodes = children.map { |child| child.joins(joins).order(orders) } + nodes = children.map { |child| child.except(:joins).joins(joins).order(orders) } nodes.reduce(&:and) in :or joins = children.flat_map(&:joins_values) orders = children.flat_map(&:order_values) - nodes = children.map { |child| child.joins(joins).order(orders) } + nodes = children.map { |child| child.except(:joins).joins(joins).order(orders) } nodes.reduce(&:or) end end diff --git a/test/unit/post_query_builder_test.rb b/test/unit/post_query_builder_test.rb index 08c6be0cd..2b7b3f591 100644 --- a/test/unit/post_query_builder_test.rb +++ b/test/unit/post_query_builder_test.rb @@ -315,6 +315,23 @@ class PostQueryBuilderTest < ActiveSupport::TestCase assert_tag_match([post2, post1], "ordfav:#{CurrentUser.user.name} -has:comments") end + should "allow the ordfav: metatag to be combined with other metatags" do + post1 = create(:post, tag_string: "fav:#{CurrentUser.user.name}", media_asset: build(:media_asset, image_width: 800, image_height: 600, file_size: 1234, file_ext: "jpg")) + post2 = create(:post, tag_string: "fav:#{CurrentUser.user.name}", media_asset: build(:media_asset, image_width: 1920, image_height: 1080, file_size: 4567, file_ext: "png")) + + assert_tag_match([post1], "ordfav:#{CurrentUser.user.name} ratio:4/3") + assert_tag_match([post1], "ratio:4/3 ordfav:#{CurrentUser.user.name}") + + assert_tag_match([post2], "ordfav:#{CurrentUser.user.name} ratio:16/9") + assert_tag_match([post2], "ratio:16/9 ordfav:#{CurrentUser.user.name}") + + assert_tag_match([post1], "ordfav:#{CurrentUser.user.name} width:800") + assert_tag_match([post1], "ordfav:#{CurrentUser.user.name} height:600") + assert_tag_match([post1], "ordfav:#{CurrentUser.user.name} mpixels:0.48") + assert_tag_match([post1], "ordfav:#{CurrentUser.user.name} filesize:1234") + assert_tag_match([post1], "ordfav:#{CurrentUser.user.name} filetype:jpg") + end + should "return posts for the pool: metatag" do SqsService.any_instance.stubs(:send_message)