Rails:如何按计算的日期差异排序?

时间:2017-09-22 05:16:19

标签: ruby-on-rails rails-activerecord

我的模型中有一个计算字段如下。

class Products < ApplicationRecord
attr_reader :days

def days
  (Date.today - self.created_at).to_i
end

end

当我尝试对其进行排序时,我收到错误。

@products = Product.all.order("days").paginate(:page => params[:page], :per_page => 15)

错误:

PG::UndefinedColumn: ERROR:  column "days" does not exist

如果有人能告诉我如何根据计算字段进行排序,我将不胜感激?

3 个答案:

答案 0 :(得分:1)

上面代码的问题是attr_reader:days,同时你声明为方法不是变量的天数

这是我对你的问题的看法

在您的模型中

class Products < ApplicationRecord

    def total_days
      (Date.today - self.created_at).to_i
    end

    def self.sorted_by_days
      Product.all.sort_by(&:total_days).reverse
      # just delete .reverse incase you want ascending
      # I put reverse in case you want to sort descending
    end

end
控制器中的

@products = Product.sorted_by_days.paginate(:page => params[:page], :per_page => 15)

答案 1 :(得分:1)

Rails order 子句参数columb应该存在于表中,不支持模型中用户定义的自定义属性。因此,您必须将ruby sort_by 方法用于自定义属性,如下所示,

Product.all.sort_by(&:days)

而且你必须改变你的方法,如下所示,

def days
  DateTime.now.to_i - self.created_at.to_i
end

它只会工作,但这不是根据自定义用户定义的自定义属性对记录进行排序的最佳做法。因此,您必须将此逻辑移至sql查询本身,如下所示,

Product.all.order("now() - created_at")

它适用于postgres,不确定mysql,如果不能正常工作,请在mysql中检查备用。

答案 2 :(得分:1)

我不确定你是如何运行这段代码的:

(Date.today - self.created_at).to_i

因为它需要一个带有-符号的数值。我能够这样做:

((Time.zone.now - self.created_at) / 1.day).to_i

但重点是我认为您希望按created_at日期订购记录。所以默认情况下它是升序的,你想要显示最近创建的记录,这样你就可以直接这样做了:

Product.all.order(:created_at)

如果你想按降序排列,那么你可以这样做:

Product.all.order(created_at: :desc)

如果您需要sort attr_reader,其他答案仍会显示如何执行此操作。问题是pagination适用于ActiveRecord::Collection而不是数组,因此will_paginate可能会在这里提及:

Ruby on Rails will_paginate an array

希望这有帮助。