我对rails(和开发)很陌生,并且需要创建更改日志。假设你有一张员工表。在该表上,您有一个员工参考号,名字和姓氏。当名字或姓氏发生变化时,我需要将其记录到某个地方以便以后报告。我只需要记录更改,因此如果员工ref 1从Bill更改为Bob,那么我需要将引用号和名字放入表中。更改表可以包含mnight更改的所有列,但大多数列仅填充参考编号和更改的字段。我也不需要先前的值,只需要新的值。希望有道理。
看看纸质小道等宝石,但它们看起来非常复杂。我不需要操纵模型或移动版本等,我只需要跟踪哪些字段已更改,何时以及由谁更改。
我很感激你的推荐。
答案 0 :(得分: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
答案 1 :(得分:1)
我推荐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"
答案 2 :(得分: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
端
那就是它。如果帐户启用它,应用程序会关注特定字段,然后对这些字段的所有更改都会记录到表中,从而创建一个简单的审计跟踪。