最近、当社でコンプライアンスの推進を開始し、現在Railsアプリケーションで管理されているデータへの変更の完全な履歴を保持する必要があります. すべてのアクションを説明するものをログ ファイルにプッシュするだけでOKです。これはかなり目立たない方法です。
私の傾向は、で次のようなことをすることです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
一般に、これはうまく機能しますが、 has_many<association>_ids
:through => 関連付けに追加された「魔法の」メソッドを使用すると失敗します。
例えば:
# 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_destroy
ときにトリガーされません。RunwayModel
私の質問は...それらの変更(および/または潜在的に他の削除)を監視するように機能させる方法はありますか?
まだ比較的目立たないより良い解決策はありますか?