【问题标题】:Ordering Records with Same Date Using Second Field使用第二个字段对具有相同日期的记录进行排序
【发布时间】:2014-08-31 21:38:36
【问题描述】:

我有一个包含许多画廊的应用程序。每个画廊都有一个 start_date DateTime 字段。

由于遗留原因,所有 start_dates 的时间都是午夜。

Thu, 10 Jul 2014 00:00:00 UTC +00:00

我需要按日期对画廊进行排序,以便用户可以使用“旧”和“新”链接在它们之间来回移动。画廊是根据 start_date 排序的:

scope :start_date_ascending, -> { order(start_date: :asc) }
scope :start_date_descending, -> { order(start_date: :desc) }

我的问题是当有多个相同日期的画廊时,没有明确的旧画廊或新画廊。在这种情况下,我无法预测返回相同日期的画廊的顺序,因此跨多个相同日期的画廊移动变得随机且容易出错。

我设置了查找新旧画廊的范围:

scope :newer_than, -> (gallery){ where.not(id:gallery).where('start_date >= :gallery_start_date', gallery_start_date:gallery.start_date) }
scope :older_than, -> (gallery){ where.not(id:gallery).where('start_date < :gallery_start_date', gallery_start_date:gallery.start_date) }

我发现下一个和以前的画廊是这样的:

def self.next_newer(gallery)
  Gallery.newer_than(gallery).start_date_ascending.limit(1).first
end

def self.next_older(gallery)
  Gallery.older_than(gallery).start_date_descending.limit(1).first
end

所以在我看来,我需要一种辅助方式来订购同一日期的画廊。顺序无关紧要 - 可能只是他们的 ID。

我该如何处理这种情况,以便具有相同日期的画廊以可预测的固定顺序出现在查询中,以便 next_newernext_older 在它们之间移动?

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-4 scope arel


    【解决方案1】:

    也许您可以使用第二个条件进行排序,例如 name 如果可用,甚至是 id

    scope :start_date_ascending, -> { order(start_date: :asc, name: :asc) }
    scope :start_date_descending, -> { order(start_date: :desc, name: :asc) }
    

    注意start_date_descending 范围,保留名称asc 会很好,因此尽管日期顺序是降序,我们仍保持字母顺序

    对于下一个和上一个画廊,如果您可以存储一个数组,则可以获取您的有序 id 并遍历它们

    ids = Gallery.start_date_ascending.pluck :id
    

    【讨论】:

    • 谢谢。虽然这确实可以处理订单,但它并不能解决查询问题。我仍然需要一种方法来确保查询返回给定画廊之前或之后的画廊。然后我如何查询在给定画廊之前具有 start_date 的画廊或(具有相同的日期并且名称早于给定画廊)
    • 你能存储ids 的数组吗? ids = Gallery.start_date_ascending.pluck :id。然后遍历那个数组
    【解决方案2】:

    基于@BengaminSinclaire 的建议:

      def self.next_newer(gallery)
        ascending_ids = Gallery.start_date_ascending.pluck :id
        current_index = ascending_ids.index(gallery.id)
        Gallery.find(ascending_ids[current_index+1]) if current_index < ascending_ids.length - 1
      end
    
      def self.next_older(gallery)
        ascending_ids = Gallery.start_date_ascending.pluck :id
        current_index = ascending_ids.index(gallery.id)
        Gallery.find(ascending_ids[current_index-1]) if current_index > 0
      end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-19
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多