如何比较上一个条目

时间:2018-11-08 15:25:30

标签: ruby-on-rails ruby

我有一张消费表

  create_table "consumptions", force: :cascade do |t|
    t.float "kilometers"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "user_id"
  end

这是用户1的消费列表

 #<Consumption:0x007f8654895080     
  id: 1,
  kilometers: 10000.0,
  created_at: Wed, 07 Nov 2018 15:23:21 UTC +00:00,
  updated_at: Wed, 07 Nov 2018 15:23:21 UTC +00:00,
  user_id: 1>,
 #<Consumption:0x007f865489c268
  id: 4,
  kilometers: 10800.0,
  created_at: Wed, 24 Oct 2018 14:30:23 UTC +00:00,
  updated_at: Thu, 08 Nov 2018 12:35:37 UTC +00:00,
  user_id: 1>,
 #<Consumption:0x007f8654893f50
  id: 6,
  kilometers: 11400.0,
  created_at: Thu, 08 Nov 2018 11:56:52 UTC +00:00,
  updated_at: Thu, 08 Nov 2018 12:36:42 UTC +00:00,
  user_id: 1>,

我想比较每次消费之间的公里数差异 ...

consumptions

id |   km  | 
1  | 10000 | 
4  | 10800 | 
6  | 11400 | 

id 1和4之间的结果应为800

4到6之间的结果应该是600

4 个答案:

答案 0 :(得分:1)

我建议您看看https://github.com/geokit/geokit-rails 您只需要向模型中添加acts_as_mappable(确定是配置默认值还是将其放置在模型中,我认为最好是在配置文件中完成此操作)。

然后,您只需使用by_distance方法,您的代码就会看起来非常好:)

答案 1 :(得分:0)

您正在使用哪个数据库?

基本上,您想使用窗口功能:

例如对于PostgreSQL:

select id, kilometers - lag(kilometers) over (order by id) as difference? from consumptions;

PostgreSQL reference

MySQL reference

Another example on SO

然后find_by_sql建议使用here来检索值作为ActiveRecord模型。

  

结果将作为具有请求的列的数组返回   封装为您从中调用此方法的模型的属性。

我还没有尝试过,但是您的看起来像这样:

Consumptions.find_by_sql('select id, kilometers - lag(kilometers) over (order by id) as difference? from consumptions')

答案 2 :(得分:0)

给出更多的“红宝石”答案:

def difference_in_km(obj_1, obj_2)
  (obj1.kilometers - obj2.kilometers).abs
end

abs可以处理负数,例如返回400而不是-400。

这可让您执行以下操作:

con_1 = Consumption.find(1)
con_2 = Consumption.find(4)

difference_in_km(con_1, con_2)

另一种方法是将一个实例方法添加到您的Consumption类:

class Consumption < ApplicationRecord
  ....
  ....

  def distance_from(other_consumption)
    (kilometers - other_consumption.kilometers).abs
  end
end

这将允许您执行以下操作:

con_1.distance_from(con_2)

答案 3 :(得分:0)

我找到了一种更简单的方法:

因此,我将difference的属性默认设置为0consumptions

class Consumption < ApplicationRecord
    belongs_to :user

    before_save :count_difference

    def count_difference
        if Consumption.any?
            if Consumption.last.user_id == self.user_id
                self.difference = Consumption.last.kilometers - self.kilometers
            end
        end
    end

end