J. Jackson
J. Jackson

Reputation: 3744

Searching has_many association with Searchkick

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

Answers (1)

Oshan Wisumperuma
Oshan Wisumperuma

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

Related Questions