Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to associate arel table alias nodes to a search model #443

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

sholden
Copy link

@sholden sholden commented Jun 24, 2020

Add the ability to associate Arel::Nodes::TableAlias objects to a PgSearch::Model. This allows us to build an Arel AST directly to allow searching across relations where ActiveRecord won't support joins (in our use case and in the specs, this involves a polymorphic association), but you could imagine many more use cases where this feature could make the PgSearch::Model configuration much more flexible and extensible.

Example from spec:

model do
  include PgSearch::Model
  has_many :other_models, :class_name => 'AssociatedModelWithHasManyAndPolymorphicPet', :foreign_key => 'ModelWithHasMany_id'

  def self.associated_pet_names
    cat_table = AssociatedCat.arel_table
    dog_table = AssociatedDog.arel_table
    bt_table = AssociatedModelWithHasManyAndPolymorphicPet.arel_table

    cat_join = bt_table.join(cat_table).on(bt_table[:polymorphic_pet_id].eq(cat_table[:id]).and(bt_table[:polymorphic_pet_type].eq('AssociatedCat')))
                   .project(bt_table[:ModelWithHasMany_id].as('id'), cat_table[:cat_name].as('name'))
    dog_join = bt_table.join(dog_table).on(bt_table[:polymorphic_pet_id].eq(dog_table[:id]).and(bt_table[:polymorphic_pet_type].eq('AssociatedDog')))
                   .project(bt_table[:ModelWithHasMany_id].as('id'), dog_table[:dog_name].as('name'))

    union = cat_join.union(dog_join)
    Arel::Nodes::TableAlias.new(union, 'associated_pet_names')
  end

  pg_search_scope :with_associated,
                  against: :title,
                  associated_against: {
                      other_models: [:title]
                  },
                  associated_arel: {
                      associated_pet_names => :name
                  }
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant