当在elasticsearch-rails中将kaminari和includes结合使用时,会出现错误的问题。我们需要解决这个问题

如果通过正常方式将“includes”应用于Elasticsearch的返回值,会出现错误。
由于Bullet无法检测到N+1警告,因此很容易被忽视。
这是一个备忘录。

只需要一个选项

由于elasticsearch_rails内建有kaminari模块,因此可以通过在elasticsearch的返回结果中添加下面的page参数来实现分页功能。

class SampleModelsController < ApplicationController
  def index
    @sample_models = SampleModel.__elasticsearch__.search({query_json}).page(params[:page]).records
  end
end

View可以使用类似ActiveRecord的kaminari通用实现方式来描述,而无需意识到ElasticSearch。通过这种方式,可以实现分页功能。这是因为ElasticSearch内部有kaminari模块,通过该模块实现分页功能。

- @sample_models.each do |sample_model|
  = sample_model.title

= paginate @sample_models

問題:當嘗試添加.includes時…

然而,如果按照ActiveRecord的方式操作,可以这样做,

# NG例
class ModelsController < ApplicationController
  def index
    SampleModel.__elasticsearch__.search({query_json}).page(params[:page]).records.includes(:child_model)
  end
end

在kaminari中发生以下错误

undefined method `total_pages' for #<SampleModel::ActiveRecord_Relation:0x00************>

一旦使用.includes(:child_model)进行记录,Elasticsearch::Model::Response::Records将被转换为SampleModel::ActiveRecord_Relation,导致ElasticSearch的kaminari模块提供的参数被忽略掉,这是问题的原因。

解决方案 cè’àn)

可以利用elasticsearch_rails中的options选项来传递includes给record,这样就可以使用它。

# OK例
class SampleModelsController < ApplicationController
  def index
    SampleModel.__elasticsearch__.search({query_json}).page(params[:page]).records(includes: :child_model)
  end
end
广告
将在 10 秒后关闭
bannerAds