Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix reindex! when all of targeted records are to delete and nothing to save #452

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

metheglin
Copy link

@metheglin metheglin commented Nov 24, 2024

Q A
Bug fix? yes
New feature? no
BC breaks? no
Related Issue
Need Doc update no

What problem is this fixing?

How to reproduce

app/models/product.rb

class Product < ApplicationRecord
  enum status: {
    draft: 0,
    opened: 1,
  }

  algoliasearch if: :algolia_published? do
    attribute :title
    attribute :content
  end

  def algolia_published?
    opened?
  end
end

in rails console for instance

Product.draft.limit(3).reindex!

Got the error below

NoMethodError: undefined method `task_id' for nil:NilClass

/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/algoliasearch-rails-3.0.0/lib/algoliasearch-rails.rb:464:in `block (2 levels) in algolia_reindex!'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/relation/batches.rb:138:in `block in find_in_batches'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/relation/batches.rb:245:in `block in in_batches'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/relation/batches.rb:229:in `loop'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/relation/batches.rb:229:in `in_batches'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/relation/batches.rb:137:in `find_in_batches'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/querying.rb:22:in `find_in_batches'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/algoliasearch-rails-3.0.0/lib/algoliasearch-rails.rb:913:in `algolia_find_in_batches'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/algoliasearch-rails-3.0.0/lib/algoliasearch-rails.rb:449:in `block in algolia_reindex!'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/algoliasearch-rails-3.0.0/lib/algoliasearch-rails.rb:442:in `each'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/algoliasearch-rails-3.0.0/lib/algoliasearch-rails.rb:442:in `algolia_reindex!'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/relation/delegation.rb:108:in `public_send'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/relation/delegation.rb:108:in `block in method_missing'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/relation.rb:880:in `_scoping'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/relation.rb:428:in `scoping'
/Users/metheglin/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-7.0.2.3/lib/active_record/relation/delegation.rb:108:in `method_missing'

... (Logs continue but let me refrain from share because it includes project information)

Cause

This error happens because I'm using conditional index.
In reindex!, if any records to be deleted, it deletes from algolia and remove from activerecord target.

AlgoliaSearch.client.delete_objects(index_name, ids.select { |id| !id.blank? })

And then the rest of activerecord target to be saved.
last_task = AlgoliaSearch.client.save_objects(index_name, objects).last.task_id

But when all of the activerecord target to be deleted, there is nothing to be saved. Thus AlgoliaSearch.client.save_objects(index_name, objects) returns empty array. And then .last got nil, .task_id got undefined method.

Describe your change

I just added &. to call task_id. Sorry, I have no idea if I could use &. operator considering supported ruby version.

UPDATED: Since I reflected it's not good to use &., I have added present? check on return value of save_objects explicitly. be4ee11

When saving objects is empty, it seems there is no reason to wait task. So with using present? check, setting last_task as nil seems good enough to handle this case.
But I'm not so sure if it should wait delete_objects task. However, I think it doesn't break existing behavior with this change at least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant