0

这是我编写的一个类,用于跟踪我的 Rails 应用程序中的后台活动。

我的问题是该status字段已正确更新,但该logs字段未正确更新。知道为什么吗?

ps1:我可以在tmp_logs包含我想要的数据的日志中看到,即从根目录中找到的html文件列表)

rakeps2:此代码通过delayed_jobgem 运行。

class MaintenanceOperation < ActiveRecord::Base
  attr_accessible :logs, :status, :operation

  def track_object_elements_in_html
    status = "started"
    tmp_logs = logs
    self.save
    begin
      nb_files = 0
      html_files = File.join(my_root, "**", "*.{html,htm,HTML,HTM}")
      Dir.glob(html_files).each do |file|
        nb_files += 1
        tmp_logs << file << "\n"
        logger.debug tmp_logs
      end
      tmp_logs << "Found #{nb_files} files." << "\n"
      self.logs = tmp_logs

      self.status = "done"
    rescue Exception => e
      logger.error "Finished performing maintenance operation with error"
      logger.error e.message
      e.backtrace.each { |line| logger.error line }
      logger.error "Flagging as error"
      self.status = "error"
    end
    self.save
  end
end

编辑:

更改logs.

2013-02-18 19:15:28.981 [meh]  (0.1ms)  begin transaction (pid:80725)
2013-02-18 19:15:28.982 [meh]  (0.0ms)  commit transaction (pid:80725)
4

1 回答 1

0

我认为您在这里被活动记录的更改跟踪所吸引。简而言之,当您调用 save Active Record 时,只会更新它认为您已更新的列。特别是,如果你修改了一个属性(例如调用 gsub! 或 << ),那么 Active Record 不会发现它。

你在做

self.logs = tmp_logs

但是,tmp_logs之前设置为logs,因此self.logstmp_logs是同一个对象。在您进行分配时,Active Record 比较 self.logs 和 tmp_logs,发现它们是同一个对象,因此不会将该列标记为已更改。

您可以更改您的代码,以便 Active Record 认为您正在为日志列分配一个新值(例如将 tmp_logs 设置为 self.logs.dup),或者您可以调用logs_will_change!告诉 Active Record 您已经修改了该属性并且应该在下次调用 save 时更新它。

于 2013-02-18T18:17:20.923 回答