0

TradeDailyAverage というモデルの DB テーブルがあります。date(DateTime) & averageprice(10 進数) 列があります

これを実行すると、 averageprice 属性を更新できません。

      newaverage = TradeDailyAverage.find_or_initialize_by_date(date)
      newaverage.update_attributes :averageprice => dailyaverage

さらに、これを実行すると、日付は表示されますが、Rails コンソールに平均価格が表示されません。空白としてのみ表示されます。

newaverage = TradeDailyAverage.find_or_initialize_by_date(date)
          puts newaverage.averageprice
          puts newaverage.date

平均価格を保存する前に何か特別なことをする必要はありますか?

参考までに、Rake タスク全体を以下に示します。

averages = Trade.where('date >= ?', 7.days.ago).average(:price, :group => "DATE_TRUNC('day', date - INTERVAL '1 hour')")

    # Loops through each daily average produced above 
    averages.each do |date, avg|

    # Converts the BigDecimal to Floating Point(?)
    averagefloat = avg.to_f

    # Rounds the Daily Average to only two decimal points
    dailyaverage = number_with_precision(averagefloat, :precision => 2)

      newaverage = TradeDailyAverage.find_or_initialize_by_date(date)
      newaverage.update_attributes :averageprice => dailyaverage
4

2 に答える 2

3

使用するfind_or_initialize_by場合は、その影響について慎重に検討する必要があります。最初の例を見てみましょう:

  newaverage = TradeDailyAverage.find_or_initialize_by_date(date)
  newaverage.update_attributes :averageprice => dailyaverage

TradeDailyAverage指定されdateた がすでにデータベースにある場合、これは機能するはずです。ただし、新しいレコードが返された場合は機能しません。理由は単純で、新しいレコードがデータベースに永続化されていないためです。update_attributes永続化されていないレコードを更新する方法はありません。ここには 2 つのオプションがあります。

1.) を使用せずupdate_attributes、値を割り当てて呼び出しますsave。これは、新しいレコードと作成されたレコードの両方で機能します。

  newaverage = TradeDailyAverage.find_or_initialize_by_date(date)
  newaverage.averageprice = dailyaverage
  newaverage.save

find_or_initialize_by2.) butは使用しないでくださいfind_or_create_by。このようにして、レコードが存在しない場合、新しいレコードがデータベースに直接書き込まれます。永続update_attributes化されたレコードが常に返されるため、これで機能するはずです。このアプローチには、 を使用せずにレコードをaveragepriceデータベースに保存するという欠点があることに注意してください。私はそれをお勧めしません。

上記の説明では、2 番目の例についても説明する必要があります。

newaverage = TradeDailyAverage.find_or_initialize_by_date(date)
puts newaverage.averageprice
puts newaverage.date

averagepriceこれにより、永続化されたレコードの日付が出力されます。ただし、新しく初期化されたレコードを取得すると、日付のみが表示されます。日付オブジェクトでレコードを初期化しただけなので、averageprice既に設定されているということはありません。

于 2013-01-05T10:56:54.280 に答える
1

私の問題は、おそらくタイムゾーンの問題が原因で、データベースに保存するときにPostgreSQLが毎時時間を変更していたことです。したがって、上記のインスタンスはすべて新しいものであり、既存のモデルの属性を更新できませんでした。そのため、datetime データを日付に変換し、date db 列を datetime ではなく date に変更したところ、すべてがスムーズに機能するようになりました。Yves は上でいくつかの素晴らしい情報を提供してくれますが、それは後で私を助けてくれました。

于 2013-01-05T18:36:31.797 に答える