Skip to content

Instantly share code, notes, and snippets.

@Genkilabs
Last active August 31, 2020 14:45
Show Gist options
  • Save Genkilabs/1d35541efd7fd97258b2 to your computer and use it in GitHub Desktop.
Save Genkilabs/1d35541efd7fd97258b2 to your computer and use it in GitHub Desktop.
Rails 4 Ransacker to build subquery for searching across multiple fields in multiple polymorphic classes.
#This is how it might be used. Create your instance which could be polymorphic or just a class.
#Search using the predicate 'in' because the subquery find_term will return an ID of every record that matches.
@profile_instance = either a PetProfile or an OwnerProfile
@profile_instance.search( { :find_term_in => "has fleas", :other_ransack_term_eq => "foobar" } ).results()
class OwnerProfile < Profile
ransacker :find_term, :formatter => proc {|val| OwnerProfile.find_term(val.downcase) }, :splat_param => true, :type => :string do
arel_table[:id]
end
def self.find_term(val)
my_arel = Arel::Table.new(OwnerProfile.table_name)
my_arel.project(my_arel[:id])
.where(Arel::Nodes::InfixOperation.new('LIKE', my_arel[:self_assessment].lower, "%#{val}%")
.or(Arel::Nodes::InfixOperation.new('LIKE', my_arel[:friend_assessment].lower, "%#{val}%"))
)
end
end
class PetProfile < Profile
ransacker :find_term, :formatter => proc {|val| PetProfile.find_term(val.downcase) }, :splat_param => true, :type => :string do
arel_table[:id]
end
def self.find_term(val)
my_arel = Arel::Table.new(PetProfile.table_name)
my_arel.project(my_arel[:id])
.where(Arel::Nodes::InfixOperation.new('LIKE', my_arel[:owner_assessment].lower, "%#{val}%"))
end
end
class Profile < ActiveRecord::Base
#... anything you need for the parent class
end
@Genkilabs
Copy link
Author

You could also do this in a has_many type configuration where OwnerProfile has_many PetProfile.
In this case the query would look like
OwnerProfile.search({:find_term_or_pet_profiles_find_term_in => "has_fleas"}).result()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment