当在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