Skip to content

Commit

Permalink
Fixes, added documentation, ability to set option for all models
Browse files Browse the repository at this point in the history
  • Loading branch information
fatkodima committed Jan 31, 2018
1 parent c113b28 commit 6a6a893
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 20 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ Breaking changes

Added

- None
- Limit number of audits stored
[#405](https://github.com/collectiveidea/audited/pull/405)

Changed

Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Audited supports and is [tested against](http://travis-ci.org/collectiveidea/aud
* 2.2.8
* 2.3.5
* 2.4.2
* 2.5.0

Audited may work just fine with a Ruby version not listed above, but we can't guarantee that it will. If you'd like to maintain a Ruby that isn't listed, please let us know with a [pull request](https://github.com/collectiveidea/audited/pulls).

Expand Down Expand Up @@ -141,6 +142,33 @@ class User < ActiveRecord::Base
end
```

### Limiting stored audits

You can limit the number of audits stored for your model. To configure limiting for all audited models, put the following in an initializer:

```ruby
Audited.max_audits = 10 # keep only 10 latest audits
```

or customize per model:

```ruby
class User < ActiveRecord::Base
audited max_audits: 2
end
```

Whenever a user is updated or destroyed, extra audits are merged into newer ones and destroyed.

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

### Current User Tracking

If you're using Audited in a Rails application, all audited changes made within a request will automatically be attributed to the current user. By default, Audited uses the `current_user` method in your controller.
Expand Down
5 changes: 5 additions & 0 deletions lib/audited.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Audited
class << self
attr_accessor :ignored_attributes, :current_user_method
attr_writer :audit_class
attr_reader :max_audits

def audit_class
@audit_class ||= Audit
Expand All @@ -13,6 +14,10 @@ def store
Thread.current[:audited_store] ||= {}
end

def max_audits=(value)
@max_audits = Integer(value).abs
end

def config
yield(self)
end
Expand Down
24 changes: 14 additions & 10 deletions lib/audited/auditor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ module ClassMethods
#
# * +require_comment+ - Ensures that audit_comment is supplied before
# any create, update or destroy operation.
# * +max_audits+ - Limits the number of stored audits.
#
def audited(options = {})
# don't allow multiple calls
Expand All @@ -43,14 +44,14 @@ def audited(options = {})

class_attribute :audit_associated_with, instance_writer: false
class_attribute :audited_options, instance_writer: false
class_attribute :keep_audits, instance_writer: false
class_attribute :max_audits, instance_writer: false
attr_accessor :version, :audit_comment

self.audited_options = options
normalize_audited_options

self.audit_associated_with = audited_options[:associated_with]
self.keep_audits = audited_options[:keep_audits]
self.max_audits = audited_options[:max_audits] || Audited.max_audits

if audited_options[:comment_required]
validates_presence_of :audit_comment, if: :auditing_enabled
Expand Down Expand Up @@ -206,13 +207,7 @@ def audit_create
def audit_update
unless (changes = audited_changes).empty? && audit_comment.blank?
write_audit(action: 'update', audited_changes: changes,
comment: audit_comment) do
if keep_audits && audits.count > keep_audits.to_i
first_audit, second_audit = audits.limit(2)
second_audit.merge!(first_audit)
first_audit.destroy!
end
end
comment: audit_comment)
end
end

Expand All @@ -228,12 +223,20 @@ def write_audit(attrs)
if auditing_enabled
run_callbacks(:audit) {
audit = audits.create(attrs)
yield if block_given?
reduce_audits_if_needed if attrs[:action] != 'create'
audit
}
end
end

def reduce_audits_if_needed
if max_audits && audits.count > max_audits
first_audit, second_audit = audits.limit(2)
second_audit.merge!(first_audit)
first_audit.destroy!
end
end

def require_comment
if auditing_enabled && audit_comment.blank?
errors.add(:audit_comment, "Comment required before destruction")
Expand Down Expand Up @@ -327,6 +330,7 @@ def normalize_audited_options
audited_options[:on] = [:create, :update, :destroy] if audited_options[:on].empty?
audited_options[:only] = Array.wrap(audited_options[:only]).map(&:to_s)
audited_options[:except] = Array.wrap(audited_options[:except]).map(&:to_s)
audited_options[:max_audits] = Integer(audited_options[:max_audits]).abs if audited_options[:max_audits].present?
end
end
end
Expand Down
28 changes: 19 additions & 9 deletions spec/audited/auditor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -329,32 +329,42 @@ def non_column_attr=(val)
end
end

describe "keep_audits" do
it "should be nil by default" do
expect(Models::ActiveRecord::User.keep_audits).to be_nil
describe "max_audits" do
it "should respect global setting" do
expect(Models::ActiveRecord::User.max_audits).to eq(10)
end

it "should respect per model setting" do
previous_max_audits = Models::ActiveRecord::User.max_audits
begin
Models::ActiveRecord::User.max_audits = 5
expect(Models::ActiveRecord::User.max_audits).to eq(5)
ensure
Models::ActiveRecord::User.max_audits = previous_max_audits
end
end

it "should delete old audits when keeped amount exceeded" do
previous_keep_audits = Models::ActiveRecord::User.keep_audits
previous_max_audits = Models::ActiveRecord::User.max_audits
begin
Models::ActiveRecord::User.keep_audits = 2
Models::ActiveRecord::User.max_audits = 2
user = create_versions(2)
user.update(name: "John")
expect(user.audits.pluck(:version)).to eq([2, 3])
ensure
Models::ActiveRecord::User.keep_audits = previous_keep_audits
Models::ActiveRecord::User.max_audits = previous_max_audits
end
end

it "should not delete old audits when keeped amount not exceeded" do
previous_keep_audits = Models::ActiveRecord::User.keep_audits
previous_max_audits = Models::ActiveRecord::User.max_audits
begin
Models::ActiveRecord::User.keep_audits = 3
Models::ActiveRecord::User.max_audits = 3
user = create_versions(2)
user.update(name: "John")
expect(user.audits.pluck(:version)).to eq([1, 2, 3])
ensure
Models::ActiveRecord::User.keep_audits = previous_keep_audits
Models::ActiveRecord::User.max_audits = previous_max_audits
end
end
end
Expand Down
5 changes: 5 additions & 0 deletions spec/rails_app/config/initializers/audited.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'audited'

Audited.config do |config|
config.max_audits = 10
end

0 comments on commit 6a6a893

Please sign in to comment.