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

时间:2019-05-22 21:48:33

标签: ruby-on-rails group-by will-paginate

我注意到,当使用will_paginate 20结果页面时,将多个表group_by“昵称”连接起来,输出被分页,但是仅显示3个“昵称”(这是有道理的,因为分页是在分组依据之前对输出进行计数),但是我该如何解决那个?另外,我想显示这样的输出,并根据“昵称”列限制每页的项目数:请注意,“数据”表具有许多“首选项”。 (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

1 个答案:

答案 0 :(得分:2)

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

但是,您想要的是20条记录,其中有20多个首选项分组?

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

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

我认为,如果昵称是唯一的,即只能有1条data_res.group_by { |r| r.nickname }与相同的data记录,这就是我的建议

nickname
  

在此处加入并包括在内,以确保优先加载偏好设置,   同时符合您现有的仅使用首选项获取数据的查询

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

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

PS:您的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) 确保所有返回的INNER JOIN记录都具有关联的data,因此任何没有至少一个{{1} }可能会从您取回的记录中排除。