2016-10-10 11 views
0

正しい結果を生成するためにデータベースクエリのトラブルシューティングを支援する必要があります。これはRails 4.2.6、Ruby 2.2.4、Postgres 1.9.0データベースで開発されたフィットネスアプリです。ユーザーが新しい体の測定値を保存するとき、最後の測定からの変化(インチなど)を表示しようとしています。問題は、以前に保存したレコードの変更値が、表示ビューで正しく計算されていないことです。Rails/Postgresデータベース - dbから正しいレコードを取得できません

コントローラ/ 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> 

、ここだとここで

は、私がこれまでにコード化されてきたものです私のデータベースクエリの結果を含むテーブル。 「Calc。Change」列の値に注意してください。

+------------+-----------+------------------+--------------------+ 
| 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日)を除いて、見ての通り、「Calcの。変更」列の値が正しくありません。どのように私はクエリを設計したかに何か問題があります。

現在のところ、myクエリは、最後に保存された測定値より1つ下のレコードを「2番目の最新のウエスト測定値」として取得します。テストケースでは、それは2016-09-01で作成されたレコードです。これは、データベースに保存された最後のレコード(この場合は2016-10-01)で動作しますが、以前に保存したレコードのページビュー表示を要求すると、誤った結果が生成されます。たとえば、2016-09-01で作成したレコードと2016--08-01で作成したレコードを比較する必要があります。

クエリで「offset(1)」を使用することは私の問題の根本だと思われますが、正しいレコードを取得する方法はわかりません。レコードを反復処理するソリューションはありますか?私はこのような状況でそれをどうやって行うのか混乱していますか?

正しい変更値を生成するためにデータベースクエリを修正する方法を教えてください。より良いアプローチがあれば教えてください。ありがとうございました!

答えて

0

コントローラ - よりシンプルな実装のために保存されて保持しているモデルにメソッドを追加:ないRailsの中でそれを試してみましたが、私はあなたのような何かをする必要があると思います推測します値。お返事のための

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

ありがとうございます!このアプローチは、私が持っていたものよりもきれいで、はるかに優れています。それは素晴らしい作品です。驚くばかり。 – codeinspired

1

が、私は「レールウェイ」でこれを行うための最善の方法のわからないんだけど、ただPostgreSQLでこれを行うには、ウィンドウ関数を使用することができます。

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

は、PostgreSQLの9.3.xでこれを試してみました問題なく動作します。そのコードの間違った場所がある

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

感謝:

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

これは、次のようなロジックをできるように、あなたが、その後の測定値を読み取ることができ、そこからメンバー、の前のインスタンスが作成されます。これを見て、これを私のRailsプロジェクトにどのように適用するかを理解できるかどうかを見ていきます。クエリメソッドのコードを変更する方法を理解する必要があります。 – codeinspired

+0

未処理のSQLは、構文エラー、予期しない '、' sql = SELECT *、ウエスト - LAG(ウエスト)オーバー(ord ... – codeinspired

+0

)を実際には引用符を省略しましたか? postgresエラー?SQLを "rails dbconsole"で実行して最初に動作させてください。 –

関連する問題