繁体   English   中英

使用join和group by时,rails中的will_paginate

[英]will_paginate in rails when using join and group by

我注意到,当使用will_paginate 20结果页面时,将多个表group_by“昵称”联接起来,但对输出进行分页,但是仅显示3个“昵称”(这是有道理的,因为分页是在group by之前对输出进行计数),但是我该如何解决呢? 另外,我想显示这样的输出,并根据“昵称”列限制每页的项目数:请注意,“数据”表具有许多“首选项”。 (data.id = preferences.data_id)

{
"totalCount": 123,
  "pageInfo": {
    "currentPage": 1,
    "nextPage": 2,
    "lastPage": 8
  },
  "results": [
    {
      "data": {
        "id": 1,
        "nickname": "foo"
      },
      "preferences": [
        {
          "id": 4479,
          "created_at": "2019-05-21T00:39:45.772Z",
          "updated_at": "2019-05-21T00:39:45.772Z",
          "title": "Check Database",
          ...
        },
        ...
      ]
    },
    ...
  ]
}

  data_res = Data.paginate(page: params[:page], per_page: 
  20).joins("INNER JOIN preferences ON data.id = 
  preferences.data_id").select("data.*, preferences.*").order(id: :asc)
  data_group_by = data_res.group_by { |r| r.nickname }
  respond_to do |format|
        format.any
        format.json {
          render :json => {
              :totalCount => data_res.total_entries,
              :pageInfo => {
                  :currentPage => data_res.current_page,
                  :nextPage => data_res.next_page,
                  :total_pages => data_res.total_pages,
                  :per_page => data_res.per_page,
              },
              :results =>  data_res
          }
        }
      end

如果我正确地理解了您的问题(可能不是),则分页显示它有20条记录,但是您只看到3条记录被归还了,因为它们已被分组了?

但是,您想要的是20条记录,并且对20个首选项进行了分组?

如果是这样,我认为您可能会使查询过于复杂。

  1. 我认为您不应该使用select("data.*, preferences.*")因为它基本上只会为获取的每个首选项添加一条新记录,因此首选项可能是您要获取多少条记录的决定因素,而不是您要在其上进行分页的data +您正在向返回的每个数据动态添加其他方法以说明首选项
  2. data_res.group_by { |r| r.nickname } data_res.group_by { |r| r.nickname }似乎是不必要的,除非您的数据记录不是唯一的,在这种情况下,我会质疑将其分组的原因。

我认为,如果昵称是唯一的,即只能有1个具有相同nickname data记录,这就是我的建议

class Data
   has_many :preferences
end
class Preference
   belongs_to :data
end

在此处联接和包含以确保渴望加载首选项,同时符合仅获取具有首选项数据的现有查询

data_res = Data.joins(:preference).includes(:preference).paginate(page: params[:page], per_page: 20).order(id: :asc) # this should give you 20 records of data that has preferences

然后,您的序列化程序可以完成其余工作,以确保正确映射数据并确保您的首选项处于同一级别(使用任何序列化程序包均可实现多种方式),例如

class DataPreferencesSerializer < AMS
  attributes :data
             :preferences # or can be has_many :preferences serializer
  def data
   {id: object.id, nickname: object.nickname }
  end

  def preferences
   object.preferences
  end
end

results= ArraySerializer.new(data_res, each_serializer: DataPreferencesSerializer, root: false)

就像我说的那样,有几种方法可以实现序列化,因此上面的实现只是您可能采用的方法的一个想法,而不是特定的实现。

PS:你的INNER JOIN确保所有返回的data记录具有关联的preferences ,因此,任何data不具有至少一个preference是可能从你回来的记录排除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM