diff --git a/app/logical/concerns/searchable.rb b/app/logical/concerns/searchable.rb index f7a9eba0b..3bf5a80aa 100644 --- a/app/logical/concerns/searchable.rb +++ b/app/logical/concerns/searchable.rb @@ -643,15 +643,44 @@ module Searchable end if parameter_hash?(params[attr]) - if association.belongs_to? + if association.through_reflection? + source_association = association.source_reflection + through_association = association.through_reflection + + if source_association.macro == :belongs_to + source_foreign_key = source_association.foreign_key + source_primary_key = source_association.association_primary_key + elsif source_association.macro == :has_one + source_foreign_key = source_association.join_foreign_key + source_primary_key = source_association.join_primary_key + else + source_foreign_key = source_association.association_primary_key + source_primary_key = source_association.foreign_key + end + + if through_association.macro == :belongs_to + through_foreign_key = through_association.foreign_key + through_primary_key = through_association.association_primary_key + elsif through_association.macro == :has_one + through_foreign_key = through_association.join_foreign_key + through_primary_key = through_association.join_primary_key + else + through_foreign_key = through_association.association_primary_key + through_primary_key = through_association.foreign_key + end + + source_subquery = source_association.klass.visible(current_user).search(params[attr], current_user).reorder(nil) + through_subquery = through_association.klass.visible(current_user).where(source_foreign_key => source_subquery.select(source_primary_key)) + relation = visible(relation, attr).where(through_foreign_key => through_subquery.select(through_primary_key)) + elsif association.belongs_to? foreign_key = association.foreign_key primary_key = association.association_primary_key + relation = visible(relation, attr).where(foreign_key => model.visible(current_user).search(params[attr], current_user).reorder(nil).select(primary_key)) else foreign_key = association.association_primary_key primary_key = association.foreign_key + relation = visible(relation, attr).where(foreign_key => model.visible(current_user).search(params[attr], current_user).reorder(nil).select(primary_key)) end - - relation = visible(relation, attr).where(foreign_key => model.visible(current_user).search(params[attr], current_user).reorder(nil).select(primary_key)) end relation diff --git a/app/models/post.rb b/app/models/post.rb index 4ce3cd695..413914e29 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1412,7 +1412,7 @@ class Post < ApplicationRecord :last_comment_bumped_at, :last_commented_at, :last_noted_at, :uploader, :approver, :parent, :artist_commentary, :flags, :appeals, :notes, :comments, :children, - :approvals, :replacements], + :approvals, :replacements, :media_metadata], current_user: current_user ) diff --git a/test/factories/ai_tag.rb b/test/factories/ai_tag.rb new file mode 100644 index 000000000..efe36fc80 --- /dev/null +++ b/test/factories/ai_tag.rb @@ -0,0 +1,7 @@ +FactoryBot.define do + factory(:ai_tag) do + tag + media_asset + score { 1.0 } + end +end diff --git a/test/functional/uploads_controller_test.rb b/test/functional/uploads_controller_test.rb index e535e4ee1..9e2296386 100644 --- a/test/functional/uploads_controller_test.rb +++ b/test/functional/uploads_controller_test.rb @@ -57,6 +57,8 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest should respond_to_search({}).with { [@upload] } should respond_to_search(source: "http://example.com/foobar").with { @upload } should respond_to_search(status: "completed").with { @upload } + should respond_to_search(media_assets: { file_size: 1_000_000 }).with { @upload } + should respond_to_search(media_assets: { md5: "blah" }).with { } end end diff --git a/test/unit/concerns/searchable.rb b/test/unit/concerns/searchable.rb index 6713995d9..b56032833 100644 --- a/test/unit/concerns/searchable.rb +++ b/test/unit/concerns/searchable.rb @@ -261,15 +261,40 @@ class SearchableTest < ActiveSupport::TestCase end end - context "for a `has_many through: ...` association" do + context "for a `has_many through: has_many` association" do subject { Upload } should "work" do + @user = create(:user) @media_asset = create(:media_asset) - @upload1 = create(:upload, upload_media_assets: [build(:upload_media_asset, media_asset: @media_asset)]) - @upload2 = create(:upload, upload_media_assets: [build(:upload_media_asset, media_asset: @media_asset)]) + @upload1 = create(:upload, uploader: @user, upload_media_assets: [build(:upload_media_asset, media_asset: @media_asset)]) + @upload2 = create(:upload, uploader: @user, upload_media_assets: [build(:upload_media_asset, media_asset: @media_asset)]) + @upload3 = create(:upload, uploader: @user, upload_media_assets: [build(:upload_media_asset)]) - assert_search_equals([@upload2, @upload1], media_asset: { md5: @media_asset.md5 }) + assert_search_equals([@upload2, @upload1], media_assets: { md5: @media_asset.md5 }, current_user: @user) + end + end + + context "for a `has_one through: has_one` association" do + subject { Post } + + should "work" do + @post1 = create(:post_with_file) + @post2 = create(:post) + + assert_search_equals([@post1], media_metadata: { id: @post1.media_metadata.id }) + end + end + + context "for a `has_one through: belongs_to` association" do + subject { AITag } + + should "work" do + @post = create(:post_with_file) + @ai_tag1 = create(:ai_tag, media_asset: @post.media_asset) + @ai_tag2 = create(:ai_tag) + + assert_search_equals([@ai_tag1], post: { id: @post.id }) end end end