0

私はレール(および開発)にかなり慣れていないため、変更ログを作成する必要があります。従業員テーブルがあるとしましょう。そのテーブルには、従業員参照番号、名、姓があります。名または姓のいずれかが変更された場合、後で報告できるように、それをどこかのテーブルに記録する必要があります。変更をログに記録するだけでよいので、従業員 ref 1 が Bill から Bob に変更された場合は、参照番号と名をテーブルに入れる必要があります。変更テーブルには、夜間に変更されるすべての列を含めることができますが、ほとんどの列には参照番号と変更されたフィールドのみが入力されます。以前の値も必要ありません。新しい値だけが必要です。それが理にかなっていることを願っています。

ペーパートレイルなどの宝石を見ましたが、私が必要としているものは非常に複雑に思えます。モデルを操作したり、バージョンを移動したりする必要はありません。どのフィールドが、いつ、誰によって変更されたかを追跡するだけで済みます。

あなたの推薦をいただければ幸いです。

4

3 に答える 3

1

独自の変更ログを作成する必要がある場合は、要件に基づいて、いくつかのコールバックを使用して作成できます。最初にログ テーブルを作成します。

def up
  create_table :employee_change_logs do |t|
    t.references :employee
    # as per your spec - copy all column definitions from your employees table
  end
end

あなたのEmployeeモデルでは:

class Employee < ActiveRecord::Base
  has_many :employee_change_logs

  before_update :capture_changed_columns
  after_update :log_changed_columns

  # capture the changes before the update occurs
  def capture_changed_columns
    @changed_columns = changed
  end

  def log_changed_columns
    return if @changed_columns.empty?
    log_entry = employee_change_logs.build
    @changed_columns.each{|c| log_entry.send(:"#{c}=", self.send(c))}
    log_entry.save!
  end
end
于 2013-06-03T16:44:22.840 に答える
0

最初に行ったのは、アプリケーション コントローラーにアラウンド フィルターを配置することでした。これは、current_employee を従業員モデルに取り込む方法でした。これは、特に私のような初心者にとっては困難でした。

around_filter :set_employee_for_log, :if => Proc.new { @current_account && 
@current_account.log_employee_changes? && @current_employee }

def set_employee_for_log
  Thread.current[:current_employee] = @current_employee.id
    begin
      yield
    ensure
      Thread.current[:current_employee ] = nil
    end
  end
end

次に、従業員モデルで、監視に関心のあるフィールドを定義しました

CHECK_FIELDS = ['first_name', 'last_name', 'middle_name']

次に、変更を実際にキャプチャするためにいくつかのフックを追加しました IF ログがアカウント レベルで有効になっている場合

before_update :capture_changed_columns
after_update :log_changed_columns, :if => Proc.new { self.account.log_employee_changes? }

def capture_changed_columns
  @changed_columns = changed
  @changes = changes
end

def log_changed_columns
  e = EmployeeChangeLog.new
  Employee::CHECK_FIELDS.each do |field|
  if self.send("#{field}_changed?")
    e.send("#{field}=", self.send(field))
  end
end

if e.changed?
  e.update_attribute(:account_id, self.account.id)
  e.update_attribute(:employee_id, self.id)
  e.update_attribute(:employee_ref, self.employee_ref)
  e.update_attribute(:user_id, Thread.current[:current_employee])
  e.save
else return
end

終わり

以上です。アカウントで有効にすると、アプリは特定のフィールドを監視し、それらのフィールドへのすべての変更がテーブルに記録され、単純な監査証跡が作成されます。

于 2013-11-18T14:51:38.600 に答える