在Rake Tasks中记录原始SQL错误

时间:2016-12-22 15:41:37

标签: ruby-on-rails rails-activerecord

我在rake任务的上下文中使用原始sql批量更新(出于性能原因)。如下所示:

update_sql = Book.connection.execute("UPDATE books AS b SET
             stock = vs.stock,
             promotion = vs.promotion,
             sales = vs.sales
             FROM (values #{values_string}) AS vs
             (stock, promotion, sales) WHERE b.id = vs.id;")

虽然一切都是"透明"在本地开发中,如果在执行rails任务期间此SQL在生产中失败(例如,因为促销列为nil并且语句变为无效),则不会记录错误。

我可以通过捕获异常来手动记录这个,如下所示,但是一些允许自动记录的选项会更好。

begin
...
rescue ActiveRecord::StatementInvalid => e
        Rails.logger.fatal "Books update: ActiveRecord::StatementInvalid: "+ e.to_s
end

1 个答案:

答案 0 :(得分:0)

您可以在模型文件夹中创建自己的自定义类:  app/models/custom_sql_logger.rb

class CustomSqlLogger
  def self.debug(msg=nil)
    @custom_log ||= Logger.new("#{Rails.root}/log/custom_sql.log")
    @custom_log.debug(msg) unless msg.nil?
  end
end

然后转到rake任务,在那里您要调试更新的字段,例如lib/task/calculate_avarages.rake并调用自定义调试器:

CustomSqlLogger.debug "The field was successfully updated into DB"

我的项目示例:

require 'rake'

task :calculate_averages => :environment do
  products = Product.all

      products.each do |product|
        puts "Calculating average rating for #{product.name}..."
        product.update_attribute(:average_rating, product.reviews.average("rating"))

        CustomSqlLogger.debug "#{product.name} was susscefully updated into DB"

      end
    end

自定义调试器会将新文件custom_sql.log创建到日志文件夹中:log/custom_sql.log并保存所有信息。一段时间后要小心日志文件大小。