Asynchronously sends your ActiveRecord models for reindexing in elasticsearch by making use of tire and resque (hence the name: resque + tire = lifesaver). Lifesaver also provides the ability to traverse ActiveRecord associations to trigger the index updates of related models.
Add this line to your application's Gemfile:
gem 'lifesaver'
And then execute:
$ bundle
Or install it yourself as:
$ gem install lifesaver
Replaces the tire callbacks in your models
class Article < ActiveRecord::Base
include Tire::Model::Search
# Replace the following include with Lifesaver
# include Tire::Model::Callbacks
enqueues_indexing
end
You can suppress index updates on a per-model basis or globally using Lifesaver.suppress_indexing
(to turn suppression back off, you would use Lifesaver.unsuppress_indexing
). Lifesaver exposes two instance methods on the model level (supress_indexing
, unsuppress_indexing
) that set a model's indexing behavior for life of that instance.
class ArticlesController < ApplicationController
def suppressed_update
@article = Article.find(params[:id])
@article.attributes = params[:article]
# No reindexing will occur at all
@article.suppress_indexing
@article.save!
# Not neccessary but if saved
# after this following call,
# this article would reindex
@article.unsuppress_indexing
end
end
Lifesaver can trigger other models to reindex if you have nested models in your indexes that you would like to update. Use the notifies_for_indexing
method to indicate which related models should be marked for indexing. Any associations passed will be both updated when a model is changed (save
or destroy
) and when another model notifies it. Any associations passed in the options will only notify when the model is changed or notified when specified in the only_on_change
or only_on_notify
keys, respectively.
class Article < ActiveRecord::Base
belongs_to :author
belongs_to :category
has_many :watchers
has_one :moderator
notifies_for_indexing :author,
only_on_change: :category,
only_on_notify: [:watchers, :moderator]
end
Lifesaver will not execute any <after|before>_update_elasticsearch_index
callback hooks. Lifesaver also does not currently support percolation.
You will see two new queues: lifesaver_indexing
and lifesaver_notification
. The queue names are configurable.
In your spec_helper, you should place something similar to the following to make sure Lifesaver isn't spawning up indexing jobs unless you want it to.
config.before(:each) do
Lifesaver.suppress_indexing
end
Then, when your tests need Lifesaver to run, you should make sure you unsuppress indexing in a before
block. You may also want to run Resque inline.
describe 'some test' do
before { Lifesaver.unsuppress_indexing }
# tests go here
end
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
Please visit TODO page here