Search code examples
ruby-on-railsindexingassociationselasticsearchtire

I have a categories facet hooked into an article model, but I can't figure out how to update the category name when I change it in the category model


The problems:

  • When I goto category/edit/1 and change a category name, the old name still shows up in my facet output.
  • When I create a new category it does not get shown in my articles.category facet until I create at least one article with that category name (makes sense, but unintended).

Here's the relevant bits of the Article model:

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

  # This is just a custom module I made that does index.refresh on save/delete
  # to ensure that I'm getting a fresh view of the index on a page load.
  include ElasticSearch::RefreshIndex

  # Trimmed out a bunch of fields, but this should be enough to see what's going on.
  mapping do
    indexes :title, type: "string", analyzer: "snowball", boost: 10
    indexes :category do
      indexes :id, type: "integer", index: "not_analyzed", include_in_all: false
      indexes :name, type: "string", index: "not_analyzed"
    end
  end

  belongs_to :category, touch: true

  def self.search()
    # Trimmed out a lot of code here, but this is just the facet.
    facet "categories" do
      terms "category.name", all_terms: true
    end  
  end

  def to_indexed_json
    to_json( include: { category: { only: [:id, :name] } } )
  end
end

Here's the relevant bits of the Category model:

class Category < ActiveRecord::Base
  include Tire::Model::Search
  include Tire::Model::Callbacks
  include ElasticSearch::RefreshIndex

  mapping do
    indexes :id, type: "integer", index: "not_analyzed", include_in_all: false
    indexes :name, type: "string", analyzer: "not_analyzed", boost: 50
    indexes :description, type: "string", analyzer: "snowball"
  end

  has_many :articles, dependent: :destroy
  after_touch() { tire.update_index }
end

Here's how I'm using the categories facet in my articles/index view:

<% @articles.facets["categories"]["terms"].each do |facet| %>
  <%= facet_item "checkbox", "category_name[]",
      option_value: facet["term"],
      option_text: facet["term"],
      facet_count: facet["count"],
      param: "category_name"
  %>
<% end %>

Don't worry about what facet_item does, it's just a view helper that correctly renders a checkbox, label, count and sets the proper checked state.

What would I need to do to fix the 2 mentioned problems? The first one is most important to me but ideally I'd love to figure out how to get both working.


Solution

  • You just have to force a re-index of every article that uses the category you just edited, as soon as you edit said category