4

I'm trying to index a model when I have a has_many, :through association, but no results are being displayed.

class Business < ActiveRecord::Base
  include Tire::Model::Search
  include Tire::Model::Callbacks

  def self.search(params)
    tire.search(load: true) do
      query { string params[:q]} if params[:q].present?
    end
  end

  mapping do
    indexes :service_name
    indexes :service_description
    indexes :latitude
    indexes :longitude
    indexes :services do
      indexes :service
      indexes :description
    end
  end

  def to_indexed_json #returns json data that should index (the model that should be searched)
    to_json(methods: [:service_name, :service_description], include: { services: [:service, :description]})
  end

  def service_name
    services.map(&:service)
  end

  def service_description
    services.map(&:description)
  end

  has_many :professionals
  has_many :services, :through => :professionals

end

Then this is Service model

class Service < ActiveRecord::Base
  attr_accessible :service, :user_id, :description
  belongs_to :professional
  belongs_to :servicable, polymorphic: true
end

I've also reindex using this:

rake environment tire:import CLASS=Business FORCE=true

I can search for the items in Business, but when I tried to search something in Service, I get an empty result.

hellomello
  • 8,219
  • 39
  • 151
  • 297

3 Answers3

5

After struggling with mapping, I created a gem to make search a bit easier. https://github.com/ankane/searchkick

You can use the search_data method to accomplish this:

class Business < ActiveRecord::Base
  searchkick

  def search_data
    {
      service_name: services.map(&:name),
      service_description: services.map(&:description)
    }
  end
end
Andrew Kane
  • 3,200
  • 19
  • 40
  • Do I still need Tire? Because I'm trying to use searchkick, but I'm getting this error using Tire, and I tried to disconnect it and now I can't search without Tire. – hellomello Nov 03 '13 at 17:29
  • Searchkick uses Tire internally, but you want to remove all Tire-related code when you use it, like to_indexed_json, mapping, etc. – Andrew Kane Nov 03 '13 at 21:53
  • I'm getting a 500 error `Tire::Search::SearchRequestFailed`, I removed everything but just did `@biz = Business.search params[:q]`, I also kept the `include Tire` stuff – hellomello Nov 03 '13 at 21:59
  • You'll need to remove the include Tire, run Business.reindex, and to make sure the correct data is indexed, check a few business records. `Business.first.search_data` – Andrew Kane Nov 03 '13 at 22:08
  • I removed the include, and reindex. I'm still getting a 500 error `Tire::Search::SearchRequestFailed` Not exactly sure whats going on. I commented out all the Tire-related codes – hellomello Nov 03 '13 at 22:17
  • Thanks for helping me. I have copied and pasted the error message I got from using searchkick https://gist.github.com/andiruleu/7295695 – hellomello Nov 03 '13 at 22:39
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/40473/discussion-between-andrew-kane-and-andrewliu) – Andrew Kane Nov 03 '13 at 23:31
3

I do not believe there is a way to do mapping on associations with Tire. What you will want to do instead is define easily searchable fields with the :as method and a proc. This way you can also get rid of the to_indexed_json method (you will actually need to)

mapping do
  indexes :service_name
  indexes :service_description
  indexes :latitude
  indexes :longitude    
  indexes :service_name, type: 'string', :as => proc{service_name}
  indexes :service_description, type: 'string', :as => proc{service_description}
end
Houen
  • 1,039
  • 1
  • 16
  • 35
  • This method still doesn't work for me. I'm still getting zero outputs – hellomello Nov 03 '13 at 04:25
  • Have you re-indexed your models? If so, try using the Sense chrome extension to browse your created indexes, just to see whether you have any data in the new columns. – Houen Nov 03 '13 at 15:26
  • I did re-index the model, and i checked sense, it just gives me empty array. I'm not sure if its exactly getting the model from `services` – hellomello Nov 03 '13 at 19:25
  • I'm able to get professionals model, but I'm not able to get services? – hellomello Nov 03 '13 at 20:20
0

Tire can associate with associations, I've used it to index on has_many association but have not tried has_many, :through yet. Try index on object?

mapping do
  indexes :service_name
  indexes :service_description
  indexes :latitude
  indexes :longitude
  indexes :services, type: 'object',
    properties: {
      service: {type: 'string'}
      description: {type: 'string'}
    }
end

Also, it might be good to have a touch method :

class Service < ActiveRecord::Base
  attr_accessible :service, :user_id, :description
  belongs_to :professional, touch: true
  belongs_to :servicable, polymorphic: true
end

and after_touch callback to update the index.

Bruce Lin
  • 2,700
  • 6
  • 28
  • 38