From 43fa042eeee0e83a23b42760a9a6ec47f9942047 Mon Sep 17 00:00:00 2001 From: Mark Haussmann Date: Wed, 12 May 2021 13:19:04 +1200 Subject: [PATCH] Allow scopes that define string SQL joins --- lib/ransack/adapters/active_record/context.rb | 1 + spec/ransack/adapters/active_record/base_spec.rb | 10 ++++++++++ spec/support/schema.rb | 16 ++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/lib/ransack/adapters/active_record/context.rb b/lib/ransack/adapters/active_record/context.rb index c55257bbd..d00ca0f37 100644 --- a/lib/ransack/adapters/active_record/context.rb +++ b/lib/ransack/adapters/active_record/context.rb @@ -139,6 +139,7 @@ def remove_association(association) stashed.eql?(association) } @object.joins_values.delete_if { |jd| + jd.instance_variables.include?(:@join_root) && jd.instance_variable_get(:@join_root).children.map(&:object_id) == [association.object_id] } end diff --git a/spec/ransack/adapters/active_record/base_spec.rb b/spec/ransack/adapters/active_record/base_spec.rb index afba4e4d4..2dc740b58 100644 --- a/spec/ransack/adapters/active_record/base_spec.rb +++ b/spec/ransack/adapters/active_record/base_spec.rb @@ -78,6 +78,16 @@ module ActiveRecord expect(s.result.to_sql).to (include 'active = 1') end + it 'applies scopes that define string SQL joins' do + allow(Article) + .to receive(:ransackable_scopes) + .and_return([:latest_comment_cont]) + + # Including a negative condition to test removing the scope + s = Search.new(Article, notes_note_not_eq: 'Test', latest_comment_cont: 'Test') + expect(s.result.to_sql).to include 'latest_comment' + end + context "with sanitize_custom_scope_booleans set to false" do before(:all) do Ransack.configure { |c| c.sanitize_custom_scope_booleans = false } diff --git a/spec/support/schema.rb b/spec/support/schema.rb index 38ae219d5..a97eef87a 100644 --- a/spec/support/schema.rb +++ b/spec/support/schema.rb @@ -138,6 +138,22 @@ class Article < ActiveRecord::Base alias_attribute :content, :body default_scope { where("'default_scope' = 'default_scope'") } + scope :latest_comment_cont, lambda { |msg| + join = <<-SQL + (LEFT OUTER JOIN ( + SELECT + comments.*, + row_number() OVER (PARTITION BY comments.article_id ORDER BY comments.id DESC) AS rownum + FROM comments + ) AS latest_comment + ON latest_comment.article_id = article.id + AND latest_comment.rownum = 1 + ) + SQL + .squish + + joins(join).where("latest_comment.body ILIKE ?", "%#{msg}%") + } end class StoryArticle < Article