感觉异步更新索引不传递 record,而是在回调里构建好 elasticsearch 需要的数据传到 job 更好一点,可以很好的实现回调时 record 的状态和执行 job 时 record 的状态统一,避免了上述执行任务时记录已经不存在(或不统一)的情况:
# app/models/concerns/searchable.rb
after_destroy_commit do
SearchIndexerJob.perform_later('delete', self.class.index_name, self.class.document_type, id)
end
# app/jobs/search_indexer_job.rb
def perform(operation, index, type, id, body = nil)
client = Elasticsearch::Model.client
case operation
when 'delete'
client.delete(index: index, type: type, id: id)
end
end
关于软删除的问题,可以在软删除中添加 commit 回调,使得软删除和删除行为一致,然后就可以像上述一样当成普通删除处理了:
# app/models/concerns/soft_delete.rb
def destroy
transaction do
# 添加 destroy 回调
run_callbacks(:destroy) do
# 添加 transaction 的 commit 回调
self.class.connection.add_transaction_record(self)
# 给 commit 回调添加条件(on: :destroy)
@_trigger_destroy_callback = if persisted?
# 此处逻辑修改
time = Time.zone.now
update_columns(deleted_at: time, updated_at: time)
else
true
end
@destroyed = true
freeze
end
end
end
上述代码都是在 Rails 5.2 的环境下测试的,其他版本细节可能会有所不同