模型属性将不会更新,验证错误呼吁单独的属性不更新? [英] Model Attribute Won't Update, Validation Error Called On Separate Attribute Not Being Updated?

查看:164
本文介绍了模型属性将不会更新,验证错误呼吁单独的属性不更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的半先进的数据库查询,是要通过每小时的价格在过去的10年,回到日平均价格为过去七天:

I have the following semi-advanced DB query that is going through hourly prices for the last 10 years and returning daily average prices for the last seven days:

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

这将返回日期(这一天)和 averageprice 是这样的:

This returns the date (for that day) and an averageprice like this:

"2012-12-29 00:00:00"=>#<BigDecimal:7f97932be328,'0.2513458333 33333333E2',27(27)>

我然后通过每个响应循环,并将其保存为一个TradeDailyAverage型号新记录。

I then loop through each response and save them as new records in a TradeDailyAverage Model.

    # 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)

这工作,但由于这将是一个小时的 Rake任务,新的价格进来的每一个小时,我怎样才能改变这种先找到一个TradeDailyAverage通过日期键,如果存在的话,请更新 averageprice 属性,或创建一个新的记录,如果它不存在。

This works, but since this will be an hourly Rake Task, with new prices coming in every hour, how can I change this to first find a TradeDailyAverage by date and if it exists, update the averageprice attribute, or create a new record if it doesn't exist.

Validate_uniqueness坐落于TradeDailyAverage模型。

Validate_uniqueness is set on TradeDailyAverage Model.

更新

当我这样做,7项出现,具有精确的平均值。但是,他们是不会保存。当我添加 newaverage.save 我得到的验证错误:日期已经采取了!

When I do this, 7 items appear, with accurate averages. But they just won't save. When I add newaverage.save! I get a "Validation Error: Date has already been taken!"

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

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

Also, if I do newaverage.new_record? Ever average returns TRUE

推荐答案

这个问题(感谢亚历克斯的帮助)是由于在日期时间的差异。一旦保存到PG分贝,小时将更改日期时间。这可能是由于在分贝一个时区的问题。因此,code以上未能找到现有的记录,因为它包含了不同小时的时间比已保存在数据库中。

The issue (thanks to Alex's help) was due to a difference in the datetimes. Upon saving to a PG db, the hour would change on the datetime. This may be due to a timezone issue in the db. So, the code above could not find existing records, since it contained a different hourly time than what has been saved in the database.

由于我生产的日平均值,我不需要的时候,只要在日期列中的日期。于是,我将我的日期,以日期,以避免时间差的问题。此外,我改变了codeA位用的情况下,这样我可以报告错误。我不认为这是非常有效的,但它的工作现在。我相信,亚历克斯的解决方案上面还可以工作,只要日期时间值转换为日期与 .to_date

Since I am producing daily averages, I don't need the time, just the date in the date column. So, I converted my dates to date to avoid the time difference issue. Also I changed the code a bit with a Case, so that I can report errors. I don't think this is very efficient, but it is working for now. I believe Alex's solution above may also work as long as the datetime values are converted to dates with .to_date:

# 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 

这篇关于模型属性将不会更新,验证错误呼吁单独的属性不更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆