模型属性不会更新,在不更新的单独属性上调用validation错误?

我有以下半高级数据库查询,该查询过去10年的每小时价格并返回过去七天的每日平均价格:

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

这将返回date (当天)和averageprice如下所示:

 "2012-12-29 00:00:00"=># 

然后我遍历每个响应并将它们保存为TradeDailyAverage模型中的新记录。

  # 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) # Creates a new Object in the PpDailyAverage table TradeDailyAverage.create(date: date, averageprice: dailyaverage) 

这是有效的,但由于这将是一个每小时的佣金任务 ,每小时都有新的价格,我怎么能改变它以便按date首先找到TradeDailyAverage,如果它存在,更新averageprice属性,或创建一个新的记录,如果它不存在。

在TradeDailyAverage模型上设置Validate_uniqueness。

更新

当我这样做时,出现7个项目,具有准确的平均值。 但他们只是不会拯救。 当我添加newaverage.save! 我收到“validation错误:已经过了日期!”

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

另外,如果我做newaverage.new_record? 平均值返回TRUE

我想你想要这样的东西:

 tda = TradeDailyAverage.first_or_initialize(date: date) tda.averageprice = dailyaverage tda.save 

问题(感谢Alex的帮助)是由于日期时间的不同。 保存到PG数据库后,小时数将在日期时间内更改。 这可能是由于db中的时区问题。 因此,上面的代码无法找到现有记录,因为它包含的时间与数据库中保存的时间不同。

由于我正在生成每日平均值,因此我不需要时间,只需要日期列中的日期。 因此,我将日期转换为日期以避免时差问题。 我还使用Case更改了代码,以便我可以报告错误。 我不认为这是非常有效的,但它现在正在发挥作用。 我相信只要将日期时间值转换为.to_date日期,Alex的上述解决方案也可以正常工作:

 # Loops through each daily average produced above averages.each do |datetime, avg| # Converts the BigDecimal to Floating Point(?) avgfloat = avg.to_f # Rounds the Daily Average to only two decimal points avgprice = number_with_precision(avgfloat, :precision => 2) # Converts datetime to date since this will not work with datetime (PostgreSQL is time-zoned challenged) avgdate = datetime.to_date # These are printed to use for testing. puts avgdate puts avgprice # Starts Case to either report an error, update an existing record, or create new. case when avgdate.blank? || avgprice.blank? puts "Something went terribly wrong with your seven day averages producing algorithm." when TradeDailyAverage.exists?(:date=>avgdate) updateavg = TradeDailyAverage.find_by_date(avgdate) updateavg.averageprice = avgprice updateavg.save else TradeDailyAverage.create(:date=>avgdate, :averageprice=>avgprice) end # Ends Case end # Ends Loop for each Daily Average