2016-10-10 73 views
0

我需要幫助解決數據庫查詢問題以生成正確的結果。這是一個使用Rails 4.2.6,Ruby 2.2.4和Postgres 1.9.0數據庫開發的健身應用程序。當用戶保存新的身體測量值時,我試圖顯示自上次測量以來的更改(例如英寸)。問題是先前保存的記錄的更改值在show視圖中無法正確計算。Rails/Postgres數據庫 - 無法從數據庫檢索正確的記錄

這裏是我到目前爲止編碼:

控制器/ fitness_measurements_controller.rb:

before_action :get_second_latest_waist_measurement 

def 

get_second_latest_waist_measurement  
    @waist_second_latest_measurement = @member.fitness_measurements.order(:created_at).offset(1).last.waist || 0 

end 

fitness_measurements/show.html.erb:

<p> 
    <strong>Change in waist since last measurement:</strong> 
    <%= (@fitness_measurement.waist - @waist_second_latest_measurement).round(2) %> in 
</p> 

測試數據,這裏的一個包含我的數據庫查詢結果的表格。請注意「計算更改」列中的值。

+------------+-----------+------------------+--------------------+ 
| Date | Waist(in) | Calc. Change(in) | Correct Change(in) | 
+------------+-----------+------------------+--------------------+ 
| 2016-10-01 | 37.5 |  +1.00  |  +1.00  | 
+------------+-----------+------------------+--------------------+ 
| 2016-09-01 | 36.5 |  0.00  |  +3.00  | 
+------------+-----------+------------------+--------------------+ 
| 2016-08-01 | 33.5 |  -3.00  |  +0.05  | 
+------------+-----------+------------------+--------------------+ 
| 2016-07-01 | 33.0 |  -3.50  |  0.00  | 
+------------+-----------+------------------+--------------------+ 

正如你看到的,除了最後保存的記錄(2016年10月1日),在「計算。更改」列中的值是不正確的。我設計查詢的方式有問題。

目前,我的查詢檢索到最後一次保存的測量值下面的記錄爲「第二次最新腰圍測量」。在測試用例中,這是2016-09-01創建的記錄。這適用於保存到數據庫的最後一條記錄(在本例中爲2016-10-01),但在請求顯示先前保存的記錄的頁面視圖時會產生不正確的結果。例如,2016-09-01創建的記錄應與2016--08-01創建的記錄進行比較。

在查詢中使用「offset(1)」似乎是我的問題的根源,但我不知道如何獲得正確的記錄。是遍歷記錄的解決方案?在這種情況下,我很困惑如何做到這一點?

我應該如何解決我的數據庫查詢以生成正確的更改值?如果有更好的方法,請讓我知道。謝謝!

回答

0

控制器是該代碼錯誤的地方 - 一個更簡單的實現添加一個方法來保存的保存模型值。

def previous 
    self.class.where(member: self.member). 
      where("date < ?", self.date). 
      order(date: :desc). 
      take 
end 

這給你的成員,從中可以再讀取測量以前的實例,使邏輯,如:

@measurement.waist - @measurement.previous.waist 
+0

謝謝你的解決方案!這種方法比我所擁有的更清潔,更好。它效果很好。真棒。 – codeinspired

1

我不知道的一個「Rails的路」要做到這一點的最好辦法,但只做到這一點在PostgreSQL,您可以使用窗口函數:

SELECT *, waist - LAG(waist) OVER (order by date) as change FROM fitness_measurements WHERE member_id = ? 

試過這種PostgreSQL的9.3.x和它的工作沒有問題。沒有嘗試過在Rails的,但我猜你必須做一些事情,如:

sql = "SELECT *, waist - ..." 
FitnessMeasurement.find_by_sql(sql) 
... 
+0

感謝您的回覆。我會看看這個,看看我能不能找出如何將這個應用到我的Rails項目。需要弄清楚如何修改我的查詢方法代碼。 – codeinspired

+0

原始的SQL會導致以下錯誤:語法錯誤,意外','sql = SELECT *,腰部 - LAG(腰部)OVER(ord ... – codeinspired

+0

您是否實際上忽略了引號?是一個紅寶石錯誤還是一個postgres錯誤?我應該嘗試在「rails dbconsole」中運行SQL以使其首先工作。 –