如何在活动记录查询中选择上一行?

时间:2018-08-23 14:16:06

标签: ruby-on-rails postgresql rails-activerecord redmine

我是Rails的新手,并为Redmine制作了插件,这是我的第一个项目。我需要找出问题的状态更改之间相隔了多长时间。

我通过对每个状态更改执行以下操作来计算此值:

  • 从创建日期开始,减去前一个状态更改的创建日期
  • 如果这是问题的首次状态更改,请减去问题的创建日期。

我使用lag函数在PostgreSQL中编写了以下代码,以访问上一行,这给了我所需的输出。

SELECT issues.subject, journals.id,
COALESCE(
(journals.created_on - lag(journals.created_on) 
 OVER (PARTITION BY journals.journalized_id ORDER BY journals.created_on)),
journals.created_on - issues.created_on
) AS time_elapsed
FROM journals 
INNER JOIN journal_details ON journal_details.journal_id = journals.id
INNER JOIN issues ON issues.id = journals.journalized_id 
WHERE journal_details.prop_key = 'status_id';

...在Rails中,我做了...

Journal.joins(:details, :issue)
.where(:journal_details => {prop_key: :status_id})
.select("issues.subject, journals.id")

但是,为了选择上一行,我无法使用Postgres的函数,因为我需要此代码与数据库无关。

大约需要几个小时,我只能想到一个选择上一行的子查询的想法:

subquery = "SELECT j.created_on FROM journals AS j 
INNER JOIN journal_details ON journal_details.journal_id = j.id 
WHERE journal_details.prop_key = 'status_id' 
AND j.journalized_id = journals.journalized_id 
AND j.id < journals.id ORDER BY j.id DESC LIMIT 1"

Journal.joins(:details, :issue)
.where(:journal_details => {prop_key: :status_id})
.select("issues.subject, journals.id, 
COALESCE(journals.created_on - (#{subquery}), 
(journals.created_on - issues.created_on)) AS time_elapsed")

这不是一个可行的选择,因为它对每一行执行一个选择查询,并且我需要一种性能有效的解决方案。 (也不是DRY。)

所以我的问题是,如何使用活动记录查询界面(如果可以的话)选择上一行?或者至少,什么是解决此问题的最佳实践/铁路方式?

1 个答案:

答案 0 :(得分:0)

很抱歉,如果我在这里忽略了一些复杂性,但似乎最简单的解决方案就是跟踪rails中的先前记录?

func validateEventPasscode(){

    let api = APIService(APIKey: passcode)

    api.validatePasscode(passcode: passcode) { (event) in


        if let eventDetails = self.event {
            self.event = eventDetails
            self.view.squareLoading.stop(0.0)
            self.performSegue(withIdentifier: "showEventDashboard", sender: self)

            self.enteredEventCode.text = ""
        }