如何创建一个完整的审计日志中的Rails的每个表?创建一个、完整、日志、Rails

2023-09-08 15:57:41 作者:怀中山河.

我们最近推出了一种符合推在我们公司,都必须保持其目前在Rails应用程序管理的改变我们的数据的完整历史记录。我们已经得到了确定,简单地推入了一些描述性的每一个动作到一个日志文件,这是一个非常不显眼的路要走。

We recently began a compliance push at our company and are required to keep a full history of changes to our data which is currently managed in a Rails application. We've been given the OK to simply push something descriptive for every action to a log file, which is a fairly unobtrusive way to go.

我的倾向是做这样的事情在的ApplicationController

My inclination is to do something like this in ApplicationController:

around_filter :set_logger_username

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

然后创建一个观察员,看起来是这样的:

Then create an observer that looks something like this:

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

和一般工作原理的伟大的,但它采用了魔术时发生故障&LT;关联&​​GT; _ids 方法就是附加到的has_many :通过=>协会

and in general this works great, but it fails when using the "magic" <association>_ids method that is tacked to 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 时,新的跑道记录相关联,但不会触发 before_destroy 当 RunwayModel 被删除。

This will end up triggering the after_create when new Runway records are associated, but will not trigger the before_destroy when a RunwayModel is deleted.

我的问题是...    有没有一种方法,使其工作,这样它会观察这些变化(和/或其他可能的删除)?    有没有更好的解决方案,还是比较不显眼?

My question is... Is there a way to make it work so that it will observe those changes (and/or potentially other deletes)? Is there a better solution that is still relatively unobtrusive?

推荐答案

我对最近的一个项目类似的规定。我最终使用 acts_as_audited 的宝石,它为我们伟大的工作。

I had a similar requirement on a recent project. I ended using the acts_as_audited gem, and it worked great for us.

在我的应用程序控制器我有一个像线以下

In my application controller I have line like the following

audit RunWay,RunWayModel,OtherModelName

和它负责所有的魔力,它也保持一个日志所有被提出和谁做them--了pretty的光滑的变化。

and it takes care of all the magic, it also keeps a log of all the changes that were made and who made them-- its pretty slick.

希望它可以帮助