Skip to content

Commit a7cd5f4

Browse files
Define audit_class per model
1 parent 39d29e2 commit a7cd5f4

File tree

3 files changed

+42
-27
lines changed

3 files changed

+42
-27
lines changed

lib/audited/audit.rb

+25-17
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,38 @@ module Audited
1616
#
1717

1818
class YAMLIfTextColumnType
19-
class << self
20-
def load(obj)
21-
if text_column?
22-
ActiveRecord::Coders::YAMLColumn.new(Object).load(obj)
23-
else
24-
obj
25-
end
26-
end
19+
def initialize(model)
20+
@model = model
21+
end
2722

28-
def dump(obj)
29-
if text_column?
30-
ActiveRecord::Coders::YAMLColumn.new(Object).dump(obj)
31-
else
32-
obj
33-
end
23+
def load(obj)
24+
if text_column?
25+
ActiveRecord::Coders::YAMLColumn.new(Object).load(obj)
26+
else
27+
obj
3428
end
29+
end
3530

36-
def text_column?
37-
Audited.audit_class.columns_hash["audited_changes"].type.to_s == "text"
31+
def dump(obj)
32+
if text_column?
33+
ActiveRecord::Coders::YAMLColumn.new(Object).dump(obj)
34+
else
35+
obj
3836
end
3937
end
38+
39+
private
40+
41+
def text_column?
42+
@model.columns_hash["audited_changes"].type.to_s == "text"
43+
end
4044
end
4145

4246
class Audit < ::ActiveRecord::Base
47+
def self.inherited(klass)
48+
klass.serialize :audited_changes, YAMLIfTextColumnType.new(klass)
49+
end
50+
4351
belongs_to :auditable, polymorphic: true
4452
belongs_to :user, polymorphic: true
4553
belongs_to :associated, polymorphic: true
@@ -49,7 +57,7 @@ class Audit < ::ActiveRecord::Base
4957
cattr_accessor :audited_class_names
5058
self.audited_class_names = Set.new
5159

52-
serialize :audited_changes, YAMLIfTextColumnType
60+
serialize :audited_changes, YAMLIfTextColumnType.new(self)
5361

5462
scope :ascending, -> { reorder(version: :asc) }
5563
scope :descending, -> { reorder(version: :desc) }

lib/audited/auditor.rb

+16-9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ module Auditor #:nodoc:
1919
CALLBACKS = [:audit_create, :audit_update, :audit_destroy]
2020

2121
module ClassMethods
22+
def audit_class
23+
audit_class_name&.safe_constantize || Audited.audit_class
24+
end
25+
2226
# == Configuration options
2327
#
2428
#
@@ -67,20 +71,23 @@ def audited(options = {})
6771

6872
class_attribute :audit_associated_with, instance_writer: false
6973
class_attribute :audited_options, instance_writer: false
74+
class_attribute :audit_class_name, instance_writer: false
75+
7076
attr_accessor :audit_version, :audit_comment
7177

7278
self.audited_options = options
7379
normalize_audited_options
7480

7581
self.audit_associated_with = audited_options[:associated_with]
82+
self.audit_class_name = audited_options[:audit_class_name]
7683

7784
if audited_options[:comment_required]
7885
validate :presence_of_audit_comment
7986
before_destroy :require_comment if audited_options[:on].include?(:destroy)
8087
end
8188

82-
has_many :audits, -> { order(version: :asc) }, as: :auditable, class_name: Audited.audit_class.name, inverse_of: :auditable
83-
Audited.audit_class.audited_class_names << to_s
89+
has_many :audits, -> { order(version: :asc) }, as: :auditable, class_name: audit_class.name, inverse_of: :auditable
90+
audit_class.audited_class_names << to_s
8491

8592
after_create :audit_create if audited_options[:on].include?(:create)
8693
before_update :audit_update if audited_options[:on].include?(:update)
@@ -96,8 +103,8 @@ def audited(options = {})
96103
enable_auditing
97104
end
98105

99-
def has_associated_audits
100-
has_many :associated_audits, as: :associated, class_name: Audited.audit_class.name
106+
def has_associated_audits(audit_class_name: Audited.audit_class.name)
107+
has_many :associated_audits, as: :associated, class_name: audit_class_name
101108
end
102109
end
103110

@@ -159,14 +166,14 @@ def revisions(from_version = 1)
159166
# Returns nil for versions greater than revisions count
160167
def revision(version)
161168
if version == :previous || audits.last.version >= version
162-
revision_with Audited.audit_class.reconstruct_attributes(audits_to(version))
169+
revision_with audit_class.reconstruct_attributes(audits_to(version))
163170
end
164171
end
165172

166173
# Find the oldest revision recorded prior to the date/time provided.
167174
def revision_at(date_or_time)
168175
audits = self.audits.up_until(date_or_time)
169-
revision_with Audited.audit_class.reconstruct_attributes(audits) unless audits.empty?
176+
revision_with audit_class.reconstruct_attributes(audits) unless audits.empty?
170177
end
171178

172179
# List of attributes that are audited.
@@ -177,7 +184,7 @@ def audited_attributes
177184

178185
# Returns a list combined of record audits and associated audits.
179186
def own_and_associated_audits
180-
Audited.audit_class.unscoped
187+
audit_class.unscoped
181188
.where("(auditable_type = :type AND auditable_id = :id) OR (associated_type = :type AND associated_id = :id)",
182189
type: self.class.base_class.name, id: id)
183190
.order(created_at: :desc)
@@ -206,7 +213,7 @@ def revision_with(attributes)
206213
revision.send :instance_variable_set, "@destroyed", false
207214
revision.send :instance_variable_set, "@_destroyed", false
208215
revision.send :instance_variable_set, "@marked_for_destruction", false
209-
Audited.audit_class.assign_revision_attributes(revision, attributes)
216+
audit_class.assign_revision_attributes(revision, attributes)
210217

211218
# Remove any association proxies so that they will be recreated
212219
# and reference the correct object for this revision. The only way
@@ -431,7 +438,7 @@ def enable_auditing
431438
# convenience wrapper around
432439
# @see Audit#as_user.
433440
def audit_as(user, &block)
434-
Audited.audit_class.as_user(user, &block)
441+
audit_class.as_user(user, &block)
435442
end
436443

437444
def auditing_enabled

lib/audited/rspec_matchers.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ def reflection
221221
def association_exists?
222222
!reflection.nil? &&
223223
reflection.macro == :has_many &&
224-
reflection.options[:class_name] == Audited.audit_class.name
224+
reflection.options[:class_name] == model_class.audit_class.name
225225
end
226226
end
227227
end

0 commit comments

Comments
 (0)