我偶然发现了某条记录更新的奇怪行为。我有一个示例项目,其中我有模型餐厅,酒店,餐厅评价,酒店评价...他们几乎是不合理的,只是复制粘贴和属性中的不同名称。我有一个rake任务,我用它来填充我的数据库。在这个rake任务中,我也在为酒店和餐馆创建评级,在after_save回调中,我正在重新计算酒店和餐馆的每个属性的平均评级。相同的代码适用于酒店,但自从更新到Rails 4.2.1(它在4.0.12中工作)以来不适用于餐厅。
更新如下:
def update_restaurants_avg_rating
DA::RESTAURANT_RATING_TYPES.each do |type|
result = ActiveRecord::Base.connection.execute("SELECT AVG(restaurant_ratings.#{type}) FROM restaurant_ratings WHERE restaurant_ratings.restaurant_id = #{self.restaurant_id}").values[0][0].to_f
Restaurant.where(id: self.restaurant_id).first.update_attribute("avg_rating_#{type}", result)
end
end
在日志中没有看到更新(我可以看到酒店的更新命令但不能查看餐馆),该值不会持久存入Postgres。看起来完全不同的是在游戏中会导致这种行为。 有没有人知道,这种行为可能是什么原因?顺便说一句,我已经测试了许多可能的命令,避免使用Base.connection等。
刚刚完成,请更新酒店代码:
def update_hotels_avg_rating
DA::HOTEL_RATING_TYPES.each do |type|
result = ActiveRecord::Base.connection.execute("SELECT AVG(hotel_ratings.#{type}) FROM hotel_ratings WHERE hotel_ratings.hotel_id = #{self.hotel_id}").values[0][0].to_f
Hotel.where(id: self.hotel_id).first.update_attribute("avg_rating_#{type}", result)
end
end
编辑:我一直在深入挖掘并发现,问题可能是因为更新餐馆时,活动记录中的attribute_names为空,因此没有列更新但仍然...我不知道为什么。在这一行: https://github.com/rails/rails/blob/d937a1175f10586b892842348c1d6ecaa47aad2e/activerecord/lib/active_record/persistence.rb#L528 property_names对于餐厅是空的,但包含酒店的更新属性+“updated_at”。
但是我不确定rails的哪一部分对它负责 - 猜测某些部分的rails没有识别更新的属性。
答案 0 :(得分:0)
所以你看到一个UPDATE查询,但记录没有发生变化?
检查ROLLBACK - 如果我不得不猜测我会说验证失败了。
也许尝试update_attributes !,如果记录无效,将抛出异常。
答案 1 :(得分:0)
所以我找到了问题的根源(但不是错误) - 酒店和餐馆的迁移文件不同。酒店使用方法更改并调用t.integer等,另一方面,餐厅使用方法向上和向下并使用add_column。当我使用t.integer更改迁移以使用更改方法时,它起作用了。
有趣的是,两次迁移都在更改之前和之后创建了完全相同的表(在phppgadmin中检查)。我想这将是一个谜。