Reputation: 3744
I'm attempting to build out a search feature for my app and am running into some issues with being able to search a has_many association. I want it set up so that a user only sees items that they have access to.
In my user model, I have:
class User < ApplicationRecord
searchkick
has_many :items, -> (user) { unscope(:where).where("(consumer_type = ? and consumer_id = ?))", 'User', user.id) }, fully_load: false, dependent: :destroy
# not sure if this is helpful, was messing around with this
def search_data
{
name: items.name
}
end
end
Then in my Item model I have:
class Item < ApplicationRecord
belongs_to :consumable, polymorphic: true
belongs_to :consumer, polymorphic: true
end
Then I have two more models, "Book" and "Camera" that belong to Item. I need to be able to run a query in my controller such as:
@results = current_user.items.search('Query')
... so that it returns both Book and Camera results that match the search query. I read the Personalized Results section of the Searchkick docs, but was unable to get it to work at all. Any helpful tips, or has anybody achieved something similar scoping results to a specific user?
Upvotes: 1
Views: 847
Reputation: 1948
@results = current_user.items.search('Query')
It's not possible to search like this. and if it was then it'll hit the performance to query from both data sources and get intersect of the results set. so start from the item end and include user info to that model.
class Item
searchkick word_middle: %i[name]
def search_data
{
consumer_type: consumer.class.to_s
consumer_id: consumer.id.to_s
name: self.name
}
end
end
options = {where: [{consumer_type: 'User', consumer_id: current_user.id.to_s}]}
results = Item.search 'query', options
Upvotes: 1