ruby-on-rails - 如何在 Rails 中为每个表创建完整的审计日志?

标签 ruby-on-rails ruby activerecord observer-pattern

我们最近开始在我们公司插入合规性,并且需要保留对我们当前在 Rails 应用程序中管理的数据更改的完整历史记录。我们已经获准将每个操作的描述性内容简单地推送到日志文件,这是一种相当不引人注目的方式。

我倾向于在 ApplicationController 中做这样的事情:

around_filter :set_logger_username

def set_logger_username
  Thread.current["username"] = current_user.login || "guest"
  yield
  Thread.current["username"] = nil
end

然后创建一个看起来像这样的观察者:

class AuditObserver < ActiveRecord::Observer
  observe ... #all models that need to be observed

  def after_create(auditable)
    AUDIT_LOG.info "[#{username}][ADD][#{auditable.class.name}][#{auditable.id}]:#{auditable.inspect}"
  end

  def before_update(auditable)
    AUDIT_LOG.info "[#{username}][MOD][#{auditable.class.name}][#{auditable.id}]:#{auditable.changed.inspect}"
  end

  def before_destroy(auditable)
    AUDIT_LOG.info "[#{username}][DEL][#{auditable.class.name}][#{auditable.id}]:#{auditable.inspect}"
  end

  def username
    (Thread.current['username'] || "UNKNOWN").ljust(30)
  end
end

总的来说,这很有效很好,但在使用“魔法”<association>_ids 时失败了附加到 has_many 的方法:through => associations.

例如:

# model
class MyModel
  has_many :runway_models, :dependent => :destroy
  has_many :runways, :through => :runway_models
end

#controller
class MyModelController < ApplicationController

  # ...

  # params => {:my_model => {:runways_ids => ['1', '2', '3', '5', '8']}}

  def update
    respond_to do |format|
      if @my_model.update_attributes(params[:my_model])
        flash[:notice] = 'My Model was successfully updated.'
        format.html { redirect_to(@my_model) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @my_model.errors, :status => :unprocessable_entity }
      end
    end
  end

  # ...
end

这将最终触发 after_create当新Runway记录关联,但不会触发 before_destroyRunwayModel被删除。

我的问题是... 有没有办法让它工作,以便观察这些更改(和/或可能的其他删除)?
是否有更好的解决方案仍然相对不引人注目?

最佳答案

我在最近的一个项目中有类似的需求。我结束了使用 acts_as_audited gem,它对我们非常有用。

在我的应用程序 Controller 中,我有如下一行

audit RunWay,RunWayModel,OtherModelName

它处理所有的魔法,它还记录所有所做的更改以及所做更改的人——它非常灵活。

希望对你有帮助

关于ruby-on-rails - 如何在 Rails 中为每个表创建完整的审计日志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2381033/

相关文章:

ruby-on-rails - ActiveRecord 中的表名损坏错误

ruby - 你如何在 ruby​​ 中发送原始 header

database-design - 您应该如何对随时间变化的对象进行建模

ruby-on-rails - ActiveRecord.where(列: array_of_strings) - how to preserve order?

ruby-on-rails - 如何在相同的两个表之间建立多个多对多关系

ruby-on-rails - 没有进程运行时端口 80 显示已在使用

ruby-on-rails - Rails组错误

Ruby:行 "m = Hash.new {|h,k| h[k] = []}"完成了什么而 "Hash.new"没有完成?

activerecord - yii事件记录联接模型

ruby-on-rails - 如何将字符串转换为 ActiveSupport::TimeWithZone?