Search code examples
ruby-on-railsthinking-sphinx

ThinkingSphinx: association field UPDATE does not reindex


thinking-sphinx (3.3.0)

Rails 5.0.4

I have troubles with updating associations - ThinkingSphinx (apparently) does not reindex them.

model1

class DocRequest < ApplicationRecord
  has_many :doc_responses, :inverse_of => :doc_request, dependent: :destroy
end

model2

class DocResponse < ApplicationRecord
  belongs_to :doc_request, :inverse_of => :doc_responses
end

app/indices/doc_response_index.rb

  ThinkingSphinx::Index.define :doc_response, :with => :active_record, :delta => true do
    indexes doc_request.title, :as => :doc_request_title, :sortable => true
    indexes text

    has doc_request_id
  end

Controller:

result = DocResponse.search @keyword

When I update the title of a DocRequest model (in Admin area), ThinkingSphinx obviously does not reindex the doc_request.title field, e.g. the result = DocResponse.search @keyword query doesn't change.

What's wrong?

Running rake ts:rebuild solves the problem. But I can't do it on every update.

I tried to add a

  ThinkingSphinx::Index.define :doc_request, :with => :active_record, :delta => true do

    indexes title

  end

index and then to perform directly result = DocRequest.search @keyword - it worked correctly. But that's surely not what I need.

db/schema.rb

 create_table "doc_requests", force: :cascade do |t|
    t.string   "title"
    t.text     "text"
    t.boolean  "paid"
    t.integer  "user_id"
    t.datetime "created_at",                null: false
    t.datetime "updated_at",                null: false
    t.boolean  "delta",      default: true, null: false
    t.index ["user_id"], name: "index_doc_requests_on_user_id", using: :btree
  end

  create_table "doc_responses", force: :cascade do |t|
    t.boolean  "chosen"
    t.text     "text"
    t.float    "price"
    t.integer  "user_id"
    t.integer  "doc_request_id"
    t.datetime "created_at",                    null: false
    t.datetime "updated_at",                    null: false
    t.boolean  "delta",          default: true, null: false
    t.index ["doc_request_id"], name: "index_doc_responses_on_doc_request_id", using: :btree
    t.index ["user_id"], name: "index_doc_responses_on_user_id", using: :btree
  end

What did I do wrong? I need some help.

Can I enable some verbose console mode in ThinkingSphinx - to see the reindexing events while updating? That might be useful for debugging.

I quess that the answer is somewhere near this http://freelancing-gods.com/thinking-sphinx/deltas.html#deltas-and-associations , but what exactly to do - I don't know.


Solution

  • Thinking Sphinx does not automatically detect your associations and how they relate to your indexed data whenever you make an update to your models, as that could potentially be very complex (and thus, slow).

    You've linked to the exactly correct part of the documentation, though it's slightly out of date - you'll want to use after_commit instead. Whenever you have a DocRequest updating, you'll want to set the delta flags for all of the associated DocResponse objects:

    class DocRequest < ActiveRecord::Base
      # ...
    
      after_commit :set_response_delta_flags
    
      # ...
    
      private
    
      def set_response_delta_flags
        doc_responses.each { |response|
          response.update_attributes :delta => true
        }
      end
    
      # ...
    end
    

    Updating each response will fire off the delta processing for the affected response objects, which will in turn ensure their Sphinx data is up-to-date.