简体   繁体   English

向Rails will_paginate集合添加元素

[英]Add an element to a Rails will_paginate collection

I have a Location model that has_many LocationPhotos . 我有一个has_many LocationPhotosLocation模型。 The Location also belongs_to a single LocationPhoto as the featured_location_photo . Locationbelongs_to单个LocationPhoto作为featured_location_photo The belongs_to association looks like this: belongs_to关联如下所示:

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

Using will_paginate, I can paginate the photos for a location like this: 使用will_paginate,我可以对类似位置的照片进行分页:

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

Ideally, I would like to always include the featured_location_photo as the first element, on the first page, of the collection that's returned, and not be included again. 理想情况下,我希望始终将featured_location_photo作为返回集合的第一页上的第一个元素,而不要再次包含。 So, for example, if the related photos have ids 1,2,3,4,5,6 and the featured photo has id 3, I would want page one to show photos with ids: 因此,例如,如果相关照片的ID为1,2,3,4,5,6,而特色照片的ID为3,我希望第一页显示ID为的照片:

3, 1, 2, 4 3、1、2、4

And page two to show photos with ids: 第二页显示带有ID的照片:

5, 6 5、6

The collection should also show total_entries equal to 6. 集合还应显示等于6的total_entries

Is there any way to do this? 有什么办法吗? I can't think of a way to do it by scoping the query because there's no way to tell the featured photo to sort to the top of the results. 我无法通过限定查询范围来实现此目的,因为无法告诉特色照片排在结果的顶部。

My other thought is to first check if the location has a featured photo. 我的其他想法是,首先检查该位置是否有特色照片。 If it does, remove that from the query with a scope: 如果是这样,请使用范围将其从查询中删除:

result = location.location_photos.where.not(id: [featured_photo_id]).paginate(page: 1, per_page: 4)    

Then, I would need to add the featured photo back into the front of result . 然后,我需要将特色照片重新添加到result的前面。

I think that you could improve your models by removing the dual association and adding a column on the location photo model named featured . 我认为您可以通过删除双重关联并在location photo模型上添加一列名为featured的列来改进模型。 This way you can have more than one featured photo for each location (eventually in the future this may be needed). 这样,您可以在每个位置拥有一张以上的特色照片(最终可能会在将来使用)。 After that you can use: 之后,您可以使用:

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

And that would do the trick. 这样就可以了。

NOTE: I am aware that adding a column would cause most of the images to have an empty field on the table, but space is not a problem nowadays. 注意:我知道添加一列会导致大多数图像在表上具有一个空字段,但是如今空间已不是问题。

I'm totally saving this, because I've needed to solve this problem before and always copped out on the solution. 我完全节省了,因为我之前需要解决此问题,并且始终在解决方案中提出建议。 Thanks for making me find this!!! 感谢您让我找到这个!!!

To promote a specific record in a collection use: 要在集合使用中推广特定记录:

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

Which means you can just create a custom scope like so: 这意味着您可以像这样创建自定义范围:

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

EDIT: actually, ActiveRecord relations respond to unshift just like arrays. 编辑:实际上,ActiveRecord关系像数组一样响应unshift So all you actually need is this: 因此,您真正需要的就是:

def photos
  location_photos.unshift( featured_location_photo )
end

Which of course you can then paginate. 您当然可以分页。

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

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