将元素添加到Rails will_paginate集合

时间:2015-12-09 22:05:08

标签: ruby-on-rails will-paginate

我的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的前面。

2 个答案:

答案 0 :(得分:1)

我认为您可以通过删除双关联并在名为location photo的{​​{1}}模型上添加列来改进模型。 这样,您可以为每个位置提供多张精选照片(最终将来可能需要这样)。 之后你可以使用:

featured

这样就可以了。

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

答案 1 :(得分:1)

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

要宣传集合中的特定记录,请使用:

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

然后你可以分页。