1 分鐘閱讀

非常棒的gem

audited https://github.com/collectiveidea/audited

安裝方式

gem "audited", "~> 4.3"

rails 5.0 要加上

gem "rails-observers", github: 'rails/rails-observers'

產生table

$ rails generate audited:install
$ rake db:migrate

更新方式

如果官方有出新版本,有異動欄位,你想更新的話

$ rails generate audited:upgrade
$ rake db:migrate

使用方式

只需在您的model上 audited

class User < ActiveRecord::Base
  audited
end

預設情況下,無論何時創建,更新或刪除用戶,都會建立新的紀錄。

user = User.create!(name: "Steve")
user.audits.count # => 1
user.update_attributes!(name: "Ryan")
user.audits.count # => 2
user.destroy
user.audits.count # => 3

紀錄包含對model採取了什麼行動,以及做出了哪些修改。

user.update_attributes!(name: "Ryan")
audit = user.audits.last
audit.action # => "update"
audit.audited_changes # => {"name"=>["Steve", "Ryan"]}

可以通過索引或日期取得該次版本紀錄,或列出所有修訂版本。

user.revisions
user.revision(1)
user.revision_at(Date.parse("2016-01-01"))

限制記錄欄位

預設情況下,任何屬性更改都會建立新的紀錄。但仍可以手動指定需要紀錄的欄位。

class User < ActiveRecord::Base
  # 預設,全部欄位皆紀錄
  audited

  # 單一欄位
  audited only: :name

  # 複數欄位
  audited only: [:name, :address]

  # 排除欄位
  audited except: :password
end

特殊callback

預設情況下,可以進行新增、更新或刪除紀錄。但仍可以限定操作。

class User < ActiveRecord::Base
  # 預設,全部動作皆可
  audited

  # 限制name只紀錄更新和刪除
  audited only: :name, on: [:update, :destroy]
end

加入備註

可以在model上使用 audit_comment 屬性為每筆紀錄加入註解

user.update_attributes!(name: "Ryan", audit_comment: "Changing name, just because")
user.audits.last.comment # => "Changing name, just because"

可以選擇加入:comment_required選項,以便對所有紀錄都要求註解。

class User < ActiveRecord::Base
  audited :comment_required => true
end

追蹤使用者

如果您在Rails中,則請求中進行的所有紀錄更改將自動被列為目前使用者。預設情況下,Audited使用controller中的current_user方法。

class PostsController < ApplicationController
  def create
    current_user # => #<User name: "Steve">
    @post = Post.create(params[:post])
    @post.audits.last.user # => #<User name: "Steve">
  end
end

要使用除current_user之外的方法,請在初始化的程式碼中放入以下內容:

Audited.current_user_method = :authenticated_user

除此之外,審核也可以使用as_user方法直接指定記錄的使用者:

Audited::Audit.as_user(User.find(1)) do
  post.update_attribute!(title: "Hello, world!")
end
post.audits.last.user # => #<User id: 1>

自定義的Auditor

您可能需要不時使用自定義審核程序。它可以通過簡單的傳遞一個字符串:

class ApplicationController < ActionController::Base
  def authenticated_user
    if current_user
      current_user
    else
      'Elon Musk'
    end
  end
end

關聯的應用

有時,model相關聯很有用。例如,給定以下model:

class User < ActiveRecord::Base
  belongs_to :company
  audited
end

class Company < ActiveRecord::Base
  has_many :users
end

對使用者的每個更改都進行紀錄,但如果您想要取得屬於特定公司使用者的所有紀錄該怎麼辦?您可以使用:associated_with選項:

class User < ActiveRecord::Base
  belongs_to :company
  audited associated_with: :company
end

class Company < ActiveRecord::Base
  has_many :users
  has_associated_audits
end

現在,當使用者建立紀錄時,該用戶的公司也會一起保存。讓間接相關的公司紀錄變得更容易(也更快)。

company = Company.create!(name: "Collective Idea")
user = company.users.create!(name: "Steve")
user.update_attribute!(name: "Steve Richert")
user.audits.last.associated # => #<Company name: "Collective Idea">
company.associated_audits.last.auditable # => #<User name: "Steve Richert">

暫時禁用

如果要暫時的禁用記錄某些紀錄,有幾種方法可使用:

@user.save_without_auditing

@user.without_auditing do
  @user.save
end

指定欄位禁用

User.non_audited_columns = [:first_name, :last_name]

整個model禁用

User.auditing_enabled = false

更新時間:

留言