将元素添加到 Rails will_paginate 集合

Add an element to a Rails will_paginate collection

我有一个 Location 模型 has_many LocationPhotosLocationbelongs_to 一个 LocationPhoto 作为 featured_location_photobelongs_to 关联如下所示:

class Location < ActiveRecord::Base
  belongs_to :featured_location_photo, class_name: 'LocationPhoto', foreign_key: 'featured_location_photo_id'
end

使用 will_paginate,我可以为这样的位置的照片分页:

location.location_photos.paginate(page: 1, per_page: 4)

理想情况下,我希望始终将 featured_location_photo 作为第一个元素包括在返回的集合的第一页上,并且不再包括在内。因此,例如,如果相关照片的 ID 为 1、2、3、4、5、6,而特色照片的 ID 为 3,我希望第一页显示 ID 为:

的照片

3、1、2、4

第二页显示带 ID 的照片:

5, 6

该集合还应显示 total_entries 等于 6。

有什么办法吗?我想不出一种通过确定查询范围来做到这一点的方法,因为无法告诉特色照片排序到结果的顶部。

我的另一个想法是首先检查该地点是否有特色照片。如果是,请将其从范围为:

的查询中删除
result = location.location_photos.where.not(id: [featured_photo_id]).paginate(page: 1, per_page: 4)    

然后,我需要将精选照片重新添加到 result 的前面。

我认为您可以通过删除双重关联并在名为 featuredlocation photo 模型上添加一列来改进您的模型。 通过这种方式,您可以为每个位置拥有多张特色照片(最终将来可能需要)。 之后你可以使用:

location.location_photos.order(:featured).paginate(page: 1, per_page: 4)

这样就可以了。

注意:我知道添加一列会导致大多数图像在 table 上有一个空字段,但现在 space 不是问题。

我完全保存了这个,因为我以前需要解决这个问题并且总是在解决方案上失败。谢谢你让我找到这个!!!

要提升集合中的特定记录,请使用:

order("case when id = #{id} then 0 else id end")

这意味着您可以像这样创建一个自定义范围:

class Location < ActiveRecord::Base
  def photos
    location_photos.
      order("case when id = #{featured_location_photo_id} then 0 else id end")
  end
end

编辑: 实际上,ActiveRecord 关系响应 unshift 就像数组一样。所以你真正需要的是:

def photos
  location_photos.unshift( featured_location_photo )
end

当然你可以分页。