26
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Auditedでモデル変更を監視しよう

Last updated at Posted at 2019-06-15

AuditedというGemを業務で利用するので、予習がてら触ってみました。

ドキュメントを翻訳したものに近い内容となっております。

  • ドキュメントを読めるほど実力に自身がない人
  • ライブラリを調べる際にいろんな記事を見て時間を消耗する人

上記の方々の助けとなれば幸いです。

Auditedとは?

  • RubyのGem(ライブラリ)
  • モデルの変更を監視してくれるライブラリ

Auditedでは、「誰がその変更を行なったか」を記録したり、変更に対してコメントを付与することができます。
また、変更に関連したモデルを関連づけることも可能です。

※現在サポートされているORMはActiveRecordのみとなります。MongoMapperをサポートしていたバージョンもありましたが、詳細はドキュメントを参照ください。

前提

  • Rails 5.2.2
  • Ruby 2.5.4
  • mysql2 0.5.2
  • Audited 4.7.0

簡単なチュートリアル

まずはAuditedをインストール。Gemfileに以下を追記します。

gem "audited", "~> 4.7"

利用したいRailsアプリケーションのディレクトリでauditsテーブルを作成しましょう。
モデル変更の監視データを置くためのテーブルです。

$ rails generate audited:install
$ rake db:migrate

ここまでで下準備は完了。
Auditedを反映させたいモデルに対して、下記のようなコードを追記します。

class User < ActiveRecord::Base
  audited
end

上記の例では、Userモデルに対してAuditedを反映させています。

デフォルトではUserモデルがcreateupdatedestroy、された時、Auditsテーブルに記録されます。

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

また、auditsテーブルは「どのactionが利用されたか」や「どのような変更がなされたか」の情報を持ちます。

user.update!(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"))

実際にどのように監視データがストックされているかはauditsテーブルを参照するとわかりやすいです。
下記にカラムをまとめておきます。

 カラム名 解説
id
auditable_id 監視先テーブルにおけるid
auditable_type 監視先のモデル名
associated_id 関連モデルのid
associated_type 関連モデル名
user_id 変更を加えたUserのid
user_type 変更を加えたUser属性(ex: Admin)
username
action 変更時のアクション名(ex: action)
audited_changes 変更内容
version 変更回数
comment コメント
remote_address 操作を行なったユーザーのIPアドレス
request_uuid リクエスト時のuuid
created_at

利用Tips

特定のカラム・アクションのみ監視を行う

デフォルトでは監視先の全てのカラムに対し、createupdatedestroyアクションが行われた場合、auditsテーブルに記録します。
しかし、特定のカラム・アクションに対してのみ、監視を行うようにすることも可能です。

class User < ActiveRecord::Base
  # 全てのカラム・アクションを監視
  audited

  # nameカラムのみ監視
  audited only: :name

  # nameカラムとaddressカラムを監視
  audited only: [:name, :address]

  # passwordカラム以外を監視
  audited except: :password

  # nameカラムのupdate, destroyアクションのみを監視
  audited only: :name, on: [:update, :destroy]
end

モデルの変更にcommentを残す

モデルを変更した際、上述のカラム一覧に記載されていたcommentカラムにコメントを追加することができます。

どんな理由で変更を加えたのかが明記できて、便利ですね。

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

コメントの追加を強制することも可能です。

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

監視データの保持数を制限する

無限に蓄積されていく監視データを制限することができます。

例えば、「Userモデルの監視データは10コを超えないようにし、古いデータは削除していく」といったようなことが可能です。

config/initializer/audited.rb
Audited.max_audits = 10 # 各モデルは最新10件まで保持する

特定にモデルのみに適用することも可能です。

class User < ActiveRecord::Base
  audited max_audits: 10
end

関連モデルの監視

監視しているモデルで変更があった場合、そのモデルの親モデルも参照することが可能です。

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

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

上記のように記述することで、子モデルのUserが変更された場合、関連モデルのCompanyを参照することができます。

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

終わりに

他にも細かいユースケースに対応しているので、気になる方はぜひドキュメントを見てみてください!

26
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?