インストール編、適用編に続く関連編です。過去2回はそれぞれ以下を参照してください。
UserモデルとCompanyモデルには次のような関連を定義しているとします。まずはapp/models/user.rb。
class User < ActiveRecord::Base audited belongs_to :company end
次に、app/models/company.rb。
class Company < ActiveRecord::Base has_many :users end
このときにCompany経由でUserを作ることができるのがRailsのすごいところです。
irb(main):001:0> c = Company.create(:name => "hoge") (0.1ms) begin transaction SQL (19.6ms) INSERT INTO "companies" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", Sun, 27 May 2012 11:28:08 UTC +00:00], ["name", "hoge"], ["updated_at", Sun, 27 May 2012 11:28:08 UTC +00:00]] (12.8ms) commit transaction => #<Company id: 5, name: "hoge", created_at: "2012-05-27 11:28:08", updated_at: "2012-05-27 11:28:08"> irb(main):002:0> u = c.users.create(:name => "foo") (0.1ms) begin transaction SQL (0.7ms) INSERT INTO "users" ("company_id", "created_at", "name", "updated_at") VALUES (?, ?, ?, ?) [["company_id", 5], ["created_at", Sun, 27 May 2012 11:28:24 UTC +00:00], ["name", "foo"], ["updated_at", Sun, 27 May 2012 11:28:24 UTC +00:00]] (0.2ms) SELECT MAX("audits"."version") AS max_id FROM "audits" WHERE "audits"."auditable_id" = 2 AND "audits"."auditable_type" = 'User' SQL (0.6ms) INSERT INTO "audits" ("action", "associated_id", "associated_type", "auditable_id", "auditable_type", "audited_changes", "comment", "created_at", "remote_address", "user_id", "user_type", "username", "version") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["action", "create"], ["associated_id", nil], ["associated_type", nil], ["auditable_id", 2], ["auditable_type", "User"], ["audited_changes", "---\nname: foo\ncompany_id: 5\n"], ["comment", nil], ["created_at", Sun, 27 May 2012 11:28:24 UTC +00:00], ["remote_address", nil], ["user_id", nil], ["user_type", nil], ["username", nil], ["version", 1]] (4.0ms) commit transaction => #<User id: 2, name: "foo", company_id: 5, created_at: "2012-05-27 11:28:24", updated_at: "2012-05-27 11:28:24"> irb(main):003:0>
ここで、ちょっと注目して欲しいのは、auditsテーブルにassociated_idとかassociated_typeといった関連に関するような項目があるということ。ここに値を入れるには、モデルに対してメソッドを呼び出してあげます。
Userモデルには、auditedに対して :associated_with を追記します。
class User < ActiveRecord::Base audited :associated_with => :company belongs_to :company end
Companyモデルに対しては、 has_associated_audits を呼び出してあげます。
class Company < ActiveRecord::Base has_many :users has_associated_audits end
これで、先ほどと同じようにCompanyとUserを作成します。
irb(main):001:0> c = Company.create(:name => "hoge") (0.1ms) begin transaction SQL (18.4ms) INSERT INTO "companies" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", Sun, 27 May 2012 11:36:47 UTC +00:00], ["name", "hoge"], ["updated_at", Sun, 27 May 2012 11:36:47 UTC +00:00]] (3.6ms) commit transaction => #<Company id: 6, name: "hoge", created_at: "2012-05-27 11:36:47", updated_at: "2012-05-27 11:36:47"> irb(main):002:0> u = c.users.create(:name => "foo") (0.1ms) begin transaction SQL (0.6ms) INSERT INTO "users" ("company_id", "created_at", "name", "updated_at") VALUES (?, ?, ?, ?) [["company_id", 6], ["created_at", Sun, 27 May 2012 11:36:51 UTC +00:00], ["name", "foo"], ["updated_at", Sun, 27 May 2012 11:36:51 UTC +00:00]] Company Load (0.1ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = 6 LIMIT 1 (0.2ms) SELECT MAX("audits"."version") AS max_id FROM "audits" WHERE "audits"."auditable_id" = 3 AND "audits"."auditable_type" = 'User' SQL (0.5ms) INSERT INTO "audits" ("action", "associated_id", "associated_type", "auditable_id", "auditable_type", "audited_changes", "comment", "created_at", "remote_address", "user_id", "user_type", "username", "version") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["action", "create"], ["associated_id", 6], ["associated_type", "Company"], ["auditable_id", 3], ["auditable_type", "User"], ["audited_changes", "---\nname: foo\ncompany_id: 6\n"], ["comment", nil], ["created_at", Sun, 27 May 2012 11:36:52 UTC +00:00], ["remote_address", nil], ["user_id", nil], ["user_type", nil], ["username", nil], ["version", 1]] (3.4ms) commit transaction => #<User id: 3, name: "foo", company_id: 6, created_at: "2012-05-27 11:36:51", updated_at: "2012-05-27 11:36:51"> irb(main):003:0>
associated_idにはCompanyのidである6が、associated_typeにはCompanyが入っています。
これを使って、Userの監査証跡情報からCompanyを取得することができます。
irb(main):004:0> u.audits.first.associated Audited::Adapters::ActiveRecord::Audit Load (0.5ms) SELECT "audits".* FROM "audits" WHERE "audits"."auditable_id" = 3 AND "audits"."auditable_type" = 'User' ORDER BY version LIMIT 1 Company Load (0.2ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = 6 LIMIT 1 => #<Company id: 6, name: "hoge", created_at: "2012-05-27 11:36:47", updated_at: "2012-05-27 11:36:47"> irb(main):005:0> u.audits.first.associated Audited::Adapters::ActiveRecord::Audit Load (0.5ms) SELECT "audits".* FROM "audits" WHERE "audits"."auditable_id" = 3 AND "audits"."auditable_type" = 'User' ORDER BY version LIMIT 1 Company Load (0.2ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = 6 LIMIT 1 => #<Company id: 6, name: "hoge", created_at: "2012-05-27 11:36:47", updated_at: "2012-05-27 11:36:47"> irb(main):006:0>
逆に、Companyの関連する監査証跡情報も取得することができます。
irb(main):006:0> c.associated_audits Audited::Adapters::ActiveRecord::Audit Load (0.4ms) SELECT "audits".* FROM "audits" WHERE "audits"."associated_id" = 6 AND "audits"."associated_type" = 'Company' ORDER BY version => [#<Audited::Adapters::ActiveRecord::Audit id: 7, auditable_id: 3, auditable_type: "User", associated_id: 6, associated_type: "Company", user_id: nil, user_type: nil, username: nil, action: "create", audited_changes: {"name"=>"foo", "company_id"=>6}, version: 1, comment: nil, remote_address: nil, created_at: "2012-05-27 11:36:52">] irb(main):007:0>
ひと通り、これでauditedの紹介はオシマイです。お疲れさまでした。