In a typical Rails controller, we create a Post model and then redirect to posts_path. The index action uses Searchkick to list Posts.
# In the model
class Post < ApplicationRecord
searchkick callbacks: :async
end
# In the controller
def index
@posts = Post.search("*")
end
def create
Post.create!(post_params)
redirect_to posts_path
end
However, since Elasticsearch is eventually consistent, sometimes the redirect occur before Searchkick/Elasticsearch indexed that record.
Searchkick's docs state that one could use Post.search_index.refresh to wait for the index to catch up with the new record. So one could write:
def create
Post.create!(post_params)
Post.search_index.refresh
redirect_to posts_path
end
However, sometimes we still redirect to /posts without seeing the newly created record; I think that it's because we're using callbacks: :async, so Searchkick (and Elasticsearch::API::Indices::IndicesClient which is used behind the scenes) has no way to know about the queued Searchkick::ReindexV2Job.
If that's the case, how does one solve this use-case, which is: after the #create or #destroy action have created/destroyed a Searchkick-indexed record, redirect to the #index action making sure that the record is already on the index, when using async callbacks?
Elasticsearch::API::Indices::IndicesClient which is used behind the scenes) has no way to know about the queued Searchkick::ReindexV2Job.
Your guess is correct. It's possible that your background job hasn't been executed yet, so refreshing the search_index won't help.
To fix the issue, we need to reindex synchronously (in the same thread). Luckily you can change the reindexing strategy of Searchkick callbacks in runtime. In your scenario, I recommend to reindex synchronously via Searchkick.callbacks(:inline):
def create
# reindex synchonously
Searchkick.callbacks(:inline) do
Post.create!(post_params)
end
# ensure that all changes are reflected by the ES index
Post.search_index.refresh
redirect_to posts_path
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With