簡體   English   中英

創建Rails更改日志

[英]Creating a Rails change log

我對rails(和開發)很陌生,並且需要創建更改日志。 假設你有一張員工表。 在該表上,您有一個員工參考號,名字和姓氏。 當名字或姓氏發生變化時,我需要將其記錄到某個地方以便以后報告。 我只需要記錄更改,因此如果員工ref 1從Bill更改為Bob,那么我需要將引用號和名字放入表中。 更改表可以包含mnight更改的所有列,但大多數列僅填充參考編號和更改的字段。 我也不需要先前的值,只需要新的值。 希望有道理。

看着紙質小道等寶石,但它們看起來非常復雜。 我不需要操縱模型或移動版本等,我只需要跟蹤哪些字段已更改,何時以及由誰更改。

我很感激你的建議。

如果您堅持構建自己的更改日志,則可以根據您的要求使用一些回調來實現。 首先創建您的日志表:

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

我推薦gem vestal_versions

要版本化ActiveRecord模型,只需將版本添加到您的類中,如下所示:

class User < ActiveRecord::Base
  versioned

  validates_presence_of :first_name, :last_name

  def name
    "#{first_name} #{last_name}"
  end
end

並使用這樣的:

@user.update_attributes(:last_name => "Jobs", :updated_by => "Tyler")
@user.version # => 2
@user.versions.last.user # => "Tyler"

我們做的第一件事是在應用程序控制器中放置一個過濾器。 這就是我將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

結束

那就是它。 如果帳戶啟用它,應用程序會關注特定字段,然后對這些字段的所有更改都會記錄到表中,從而創建一個簡單的審計跟蹤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM