class PgSearch::ScopeOptions

Constants

FEATURE_CLASSES

Attributes

config[R]
feature_options[R]
model[R]

Public Class Methods

new(config) click to toggle source
# File lib/pg_search/scope_options.rb, line 9
def initialize(config)
  @config = config
  @model = config.model
  @feature_options = config.feature_options
end

Public Instance Methods

apply(scope) click to toggle source
# File lib/pg_search/scope_options.rb, line 15
def apply(scope)
  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))
    .order(Arel.sql("#{rank_table_alias}.rank DESC, #{order_within_rank}"))
    .extend(WithPgSearchRank)
    .extend(WithPgSearchHighlight[feature_for(:tsearch)])
end

Private Instance Methods

conditions() click to toggle source
# File lib/pg_search/scope_options.rb, line 92
def conditions
  expressions =
    config.features
      .reject { |_feature_name, feature_options| feature_options && feature_options[:sort_only] }
      .map { |feature_name, _feature_options| feature_for(feature_name).conditions }

  or_node(expressions)
end
feature_for(feature_name) click to toggle source
# File lib/pg_search/scope_options.rb, line 142
def feature_for(feature_name)
  feature_name = feature_name.to_sym
  feature_class = FEATURE_CLASSES[feature_name]

  raise ArgumentError, "Unknown feature: #{feature_name}" unless feature_class

  normalizer = Normalizer.new(config)

  feature_class.new(
    config.query,
    feature_options[feature_name],
    config.columns,
    config.model,
    normalizer
  )
end
include_table_aliasing_for_rank(scope) click to toggle source
# File lib/pg_search/scope_options.rb, line 169
def include_table_aliasing_for_rank(scope)
  return scope if scope.included_modules.include?(PgSearchRankTableAliasing)

  scope.all.spawn.tap do |new_scope|
    new_scope.instance_eval { extend PgSearchRankTableAliasing }
  end
end
or_node(expressions) click to toggle source
# File lib/pg_search/scope_options.rb, line 107
def or_node(expressions)
  Arel::Nodes::Or.new(expressions)
end
order_within_rank() click to toggle source

:nocov: standard:enable Lint/DuplicateMethods

# File lib/pg_search/scope_options.rb, line 120
def order_within_rank
  config.order_within_rank || "#{primary_key} ASC"
end
primary_key() click to toggle source
# File lib/pg_search/scope_options.rb, line 124
def primary_key
  "#{quoted_table_name}.#{connection.quote_column_name(model.primary_key)}"
end
rank() click to toggle source
# File lib/pg_search/scope_options.rb, line 159
def rank
  (config.ranking_sql || ":tsearch").gsub(/:(\w*)/) do
    feature_for(Regexp.last_match(1)).rank.to_sql
  end
end
rank_join(rank_table_alias) click to toggle source
# File lib/pg_search/scope_options.rb, line 165
def rank_join(rank_table_alias)
  "INNER JOIN (#{subquery.to_sql}) AS #{rank_table_alias} ON #{primary_key} = #{rank_table_alias}.pg_search_id"
end
subquery() click to toggle source
# File lib/pg_search/scope_options.rb, line 81
def subquery
  model
    .unscoped
    .select("#{primary_key} AS pg_search_id")
    .select("#{rank} AS rank")
    .joins(subquery_join)
    .where(conditions)
    .limit(nil)
    .offset(nil)
end
subquery_join() click to toggle source
# File lib/pg_search/scope_options.rb, line 128
def subquery_join
  if config.associations.any?
    config.associations.map do |association|
      association.join(primary_key)
    end.join(" ")
  end
end