diff --git a/lib/pg_search/model.rb b/lib/pg_search/model.rb index ceb7a0f1..855f062f 100644 --- a/lib/pg_search/model.rb +++ b/lib/pg_search/model.rb @@ -14,10 +14,10 @@ def pg_search_scope(name, options) raise ArgumentError, "pg_search_scope expects a Hash or Proc" end - define_singleton_method(name) do |*args| + define_singleton_method(name) do |*args, &block| config = Configuration.new(options_proc.call(*args), self) scope_options = ScopeOptions.new(config) - scope_options.apply(self) + scope_options.apply(self, &block) end end diff --git a/lib/pg_search/scope_options.rb b/lib/pg_search/scope_options.rb index b03d13d0..108c63c2 100644 --- a/lib/pg_search/scope_options.rb +++ b/lib/pg_search/scope_options.rb @@ -12,12 +12,12 @@ def initialize(config) @feature_options = config.feature_options end - def apply(scope) + def apply(scope, &block) scope = include_table_aliasing_for_rank(scope) rank_table_alias = scope.pg_search_rank_table_alias(include_counter: true) scope - .joins(rank_join(rank_table_alias)) + .joins(rank_join(rank_table_alias, &block)) .order(Arel.sql("#{rank_table_alias}.rank DESC, #{order_within_rank}")) .extend(WithPgSearchRank) .extend(WithPgSearchHighlight[feature_for(:tsearch)]) @@ -79,7 +79,7 @@ def increment_counter delegate :connection, :quoted_table_name, to: :model def subquery - model + relation = model .unscoped .select("#{primary_key} AS pg_search_id") .select("#{rank} AS rank") @@ -87,6 +87,8 @@ def subquery .where(conditions) .limit(nil) .offset(nil) + + block_given? ? yield(relation) : relation end def conditions @@ -141,8 +143,8 @@ def rank end end - def rank_join(rank_table_alias) - "INNER JOIN (#{subquery.to_sql}) AS #{rank_table_alias} ON #{primary_key} = #{rank_table_alias}.pg_search_id" + def rank_join(rank_table_alias, &block) + "INNER JOIN (#{subquery(&block).to_sql}) AS #{rank_table_alias} ON #{primary_key} = #{rank_table_alias}.pg_search_id" end def include_table_aliasing_for_rank(scope) diff --git a/spec/integration/pg_search_spec.rb b/spec/integration/pg_search_spec.rb index 056b267c..b04a62fe 100644 --- a/spec/integration/pg_search_spec.rb +++ b/spec/integration/pg_search_spec.rb @@ -8,8 +8,10 @@ table do |t| t.string "title" t.text "content" + t.integer "tenant_id", null: false, default: 1 t.integer "parent_model_id" t.integer "importance" + t.index ["tenant_id"], name: "index_model_with_pg_searches_on_tenant_id" end model do @@ -178,6 +180,19 @@ ModelWithPgSearch.pg_search_scope :search_content, against: :content end + context "when searching by tenant" do + it "uses the block to constrain the subquery to the tenant" do + ModelWithPgSearch.create!(tenant_id: 1, content: "foo") + tenant_2 = ModelWithPgSearch.create!(tenant_id: 2, content: "foo") + + results = ModelWithPgSearch.search_content("foo") do |subquery| + subquery.where(tenant_id: 2) + end + + expect(results).to eq [tenant_2] + end + end + context "when chained after a select() scope" do it "honors the select" do included = ModelWithPgSearch.create!(content: "foo", title: "bar")