• Stars
    star
    3,367
  • Rank 13,288 (Top 0.3 %)
  • Language
    Ruby
  • License
    MIT License
  • Created almost 17 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Audited (formerly acts_as_audited) is an ORM extension that logs all changes to your Rails models.

Audited Gem Version Build Status Code Climate Ruby Style Guide

Audited (previously acts_as_audited) is an ORM extension that logs all changes to your models. Audited can also record who made those changes, save comments and associate models related to the changes.

Audited currently (5.6) works with Rails 7.1, 7.0, 6.1, 6.0, 5.2.

For Rails 5.0 & 5.1, use gem version 5.4.3 For Rails 4, use gem version 4.x For Rails 3, use gem version 3.0 or see the 3.0-stable branch.

Supported Rubies

Audited supports and is tested against the following Ruby versions:

  • 2.3 (only tested on Sqlite due to testing issues with other DBs)
  • 2.4
  • 2.5
  • 2.6
  • 2.7
  • 3.0
  • 3.1
  • 3.2

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.

Supported ORMs

Audited is currently ActiveRecord-only. In a previous life, Audited worked with MongoMapper. Use the 4.2-stable branch if you need MongoMapper.

Installation

Add the gem to your Gemfile:

gem "audited"

And if you're using require: false you must add initializers like this:

#./config/initializers/audited.rb
require "audited"

Audited::Railtie.initializers.each(&:run)

Then, from your Rails app directory, create the audits table:

$ rails generate audited:install
$ rake db:migrate

By default changes are stored in YAML format. If you're using PostgreSQL, then you can use rails generate audited:install --audited-changes-column-type jsonb (or json for MySQL 5.7+ and Rails 5+) to store audit changes natively with database JSON column types.

If you're using something other than integer primary keys (e.g. UUID) for your User model, then you can use rails generate audited:install --audited-user-id-column-type uuid to customize the audits table user_id column type.

Upgrading

If you're already using Audited (or acts_as_audited), your audits table may require additional columns. After every upgrade, please run:

$ rails generate audited:upgrade
$ rake db:migrate

Upgrading will only make changes if changes are needed.

Usage

Simply call audited on your models:

class User < ActiveRecord::Base
  audited
end

By default, whenever a user is created, updated or destroyed, a new audit is created.

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

Audits contain information regarding what action was taken on the model and what changes were made.

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

You can get previous versions of a record by index or date, or list all revisions.

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

Specifying columns

By default, a new audit is created for any attribute changes. You can, however, limit the columns to be considered.

class User < ActiveRecord::Base
  # All fields
  # audited

  # Single field
  # audited only: :name

  # Multiple fields
  # audited only: [:name, :address]

  # All except certain fields
  # audited except: :password
end

Specifying callbacks

By default, a new audit is created for any Create, Update, Touch (Rails 6+) or Destroy action. You can, however, limit the actions audited.

class User < ActiveRecord::Base
  # All fields and actions
  # audited

  # Single field, only audit Update and Destroy (not Create or Touch)
  # audited only: :name, on: [:update, :destroy]
end

You can ignore the default callbacks globally unless the callback action is specified in your model using the :on option. To configure default callback exclusion, put the following in an initializer file (config/initializers/audited.rb):

Audited.ignored_default_callbacks = [:create, :update] # ignore callbacks create and update

Comments

You can attach comments to each audit using an audit_comment attribute on your model.

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

You can optionally add the :comment_required option to your audited call to require comments for all audits.

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

You can update an audit only if audit_comment is present. You can optionally add the :update_with_comment_only option set to false to your audited call to turn this behavior off for all audits.

class User < ActiveRecord::Base
  audited :update_with_comment_only => false
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 file (config/initializers/audited.rb):

Audited.max_audits = 10 # keep only 10 latest audits

or customize per model:

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

Whenever an object is updated or destroyed, extra audits are combined with newer ones and the old ones are destroyed.

user = User.create!(name: "Steve")
user.audits.count # => 1
user.update!(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.

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

To use a method other than current_user, put the following in an initializer file (config/initializers/audited.rb):

Audited.current_user_method = :authenticated_user

Outside of a request, Audited can still record the user with the as_user method:

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

The standard Audited install assumes your User model has an integer primary key type. If this isn't true (e.g. you're using UUID primary keys), you'll need to create a migration to update the audits table user_id column type. (See Installation above for generator flags if you'd like to regenerate the install migration.)

Custom Audit User

You might need to use a custom auditor from time to time. This can be done by simply passing in a string:

class ApplicationController < ActionController::Base
  def authenticated_user
    if current_user
      current_user
    else
      'Alexander Fleming'
    end
  end
end

as_user also accepts a string, which can be useful for auditing updates made in a CLI environment:

Audited.audit_class.as_user("console-user-#{ENV['SSH_USER']}") do
  post.update_attributes!(title: "Hello, world!")
end
post.audits.last.user # => 'console-user-username'

If you want to set a specific user as the auditor of the commands in a CLI environment, whether that is a string or an ActiveRecord object, you can use the following command:

Audited.store[:audited_user] = "username"

# or

Audited.store[:audited_user] = User.find(1)

Associated Audits

Sometimes it's useful to associate an audit with a model other than the one being changed. For instance, given the following models:

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

class Company < ActiveRecord::Base
  has_many :users
end

Every change to a user is audited, but what if you want to grab all of the audits of users belonging to a particular company? You can add the :associated_with option to your audited call:

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

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

Now, when an audit is created for a user, that user's company is also saved alongside the audit. This makes it much easier (and faster) to access audits indirectly related to a 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">

You can access records' own audits and associated audits in one go:

company.own_and_associated_audits

Conditional auditing

If you want to audit only under specific conditions, you can provide conditional options (similar to ActiveModel callbacks) that will ensure your model is only audited for these conditions.

class User < ActiveRecord::Base
  audited if: :active?

  def active?
    last_login > 6.months.ago
  end
end

Just like in ActiveModel, you can use an inline Proc in your conditions:

class User < ActiveRecord::Base
  audited unless: Proc.new { |u| u.ninja? }
end

In the above case, the user will only be audited when User#ninja is false.

Disabling auditing

If you want to disable auditing temporarily doing certain tasks, there are a few methods available.

To disable auditing on a save:

@user.save_without_auditing

or:

@user.without_auditing do
  @user.save
end

To disable auditing on a column:

User.non_audited_columns = [:first_name, :last_name]

To disable auditing on an entire model:

User.auditing_enabled = false

To disable auditing on all models:

Audited.auditing_enabled = false

If you have auditing disabled by default on your model you can enable auditing temporarily.

User.auditing_enabled = false
@user.save_with_auditing

or:

User.auditing_enabled = false
@user.with_auditing do
  @user.save
end

Encrypted attributes

If you're using ActiveRecord's encryption (available from Rails 7) to encrypt some attributes, Audited will automatically filter values of these attributes. No additional configuration is required. Changes to encrypted attributes will be logged as [FILTERED].

class User < ActiveRecord::Base
  audited
  encrypts :password
end

Custom Audit model

If you want to extend or modify the audit model, create a new class that inherits from Audited::Audit:

class CustomAudit < Audited::Audit
  def some_custom_behavior
    "Hiya!"
  end
end

Then set it in an initializer:

# config/initializers/audited.rb

Audited.config do |config|
  config.audit_class = "CustomAudit"
end

Enum Storage

In 4.10, the default behavior for enums changed from storing the value synthesized by Rails to the value stored in the DB. You can restore the previous behavior by setting the store_synthesized_enums configuration value:

# config/initializers/audited.rb

Audited.store_synthesized_enums = true

Support

You can find documentation at: https://www.rubydoc.info/gems/audited

Or join the mailing list to get help or offer suggestions.

Contributing

In the spirit of free software, everyone is encouraged to help improve this project. Here are a few ways you can pitch in:

  • Use prerelease versions of Audited.
  • Report bugs.
  • Fix bugs and submit pull requests.
  • Write, clarify or fix documentation.
  • Refactor code.

More Repositories

1

interactor

Interactor provides a common interface for performing complex user interactions.
Ruby
3,351
star
2

awesome_nested_set

An awesome replacement for acts_as_nested_set and better_nested_set.
Ruby
2,385
star
3

json_spec

Easily handle JSON in RSpec and Cucumber
Ruby
917
star
4

interactor-rails

Interactor Rails provides Rails support for the Interactor gem.
Ruby
436
star
5

delayed_job_active_record

ActiveRecord backend integration for DelayedJob 3.0+
Ruby
346
star
6

graticule

Graticule is a geocoding API for looking up address coordinates and performing distance calculations, supporting many popular APIs.
Ruby
299
star
7

tinder

Tinder is a Ruby API for interfacing with Campfire, the 37Signals chat application.
Ruby
258
star
8

inside_the_machine

HTML
255
star
9

acts_as_geocodable

Simple geocoding for Active Record models
Ruby
206
star
10

delayed_job_mongoid

Mongoid backend for delayed_job
Ruby
170
star
11

action_mailer_optional_tls

Enables TLS on SMTP connections (for services like GMail)
Ruby
127
star
12

command

Command provides a simple object-oriented interface for running shell commands from Ruby.
Ruby
94
star
13

sunspot_test

Auto-starts solr for your tests
Ruby
54
star
14

devise-mongo_mapper

MongoMapper ORM for Devise
Ruby
48
star
15

awesomeness

Collective Idea's Awesomeness. A collection of useful Rails bits and pieces.
Ruby
47
star
16

unicode_math

Fun Ruby extensions for doing math with Unicode
Ruby
47
star
17

calendar_builder

Ruby
45
star
18

acts_as_money

an Active Record plugin that makes it easier to work with the money gem
Ruby
45
star
19

caldav

A Ruby CalDAV client
Ruby
39
star
20

awesome-backup

Rails plugin that provides Rake and Capistrano tasks for making database backups
Ruby
32
star
21

merger

A gem for merging Active Record models
Ruby
30
star
22

html5

A Rails plugin for playing around with HTML5.
Ruby
29
star
23

with_action

A respond_to style helper for doing different actions based on which request parameters are passed.
Ruby
24
star
24

ARPlaneDetector

Use ARKit to find, and visualize horizontal and vertical planes.
Swift
23
star
25

CollectionGraph

Beautiful graphs made with UICollectionViews
Swift
23
star
26

rubymotion-parsedotcom-chat

A simple chat application written with RubyMotion and using Parse.com
Ruby
19
star
27

delayed_job_data_mapper

DataMapper backend for delayed_job
Ruby
16
star
28

deploy_and_deliver

Capistrano recipes for Pivotal Tracker. Can mark stories delivered on deploy.
Ruby
15
star
29

random_finders

A Rails plugin that allows quick and easy fetching of random records, or records in random order.
Ruby
14
star
30

searchparty

Simple site that aggregates Google, Delicious, and GitHub searches. See http://search.collectiveidea.com
JavaScript
13
star
31

pivotal_tracker

ActiveResource wrapper around v3 of the Pivotal Tracker API
Ruby
13
star
32

unifi

A ruby client for the (undocumented) Unifi AP Controller API
Ruby
12
star
33

measurement

A sweet Ruby measurement & converstion Library.
Ruby
12
star
34

clear_empty_attributes

When Active Record objects are saved from a form, empty fields are saved as empty strings instead of nil. This kills most validations.
Ruby
11
star
35

travis_bundle_cache

DEPRECATED: Cache the gem bundle for speedy travis builds (Travis now handles this)
Ruby
10
star
36

twirp-kmm

Twirp service generator and runtime for Kotlin Multiplatform projects.
Kotlin
10
star
37

seinfeld.sh

Show the date of your last commit when logging into a terminal according to Calendar About Nothing
Shell
10
star
38

fireside

Open Source Chat
Ruby
10
star
39

bender

Ruby
9
star
40

buildlight

Aggregating webhooks from multiple build services (Travis, Circle, Heroku) to power the stoplight in our office.
Ruby
9
star
41

tweet-wall

A Twitter visualizer
JavaScript
8
star
42

yardvote.com

Tracking political yard signs.
Ruby
7
star
43

chat

An example chat application
Ruby
7
star
44

simple-maps

Add Google Maps in seconds. Maps any and all hCards on the page and resizes the map to fit. Uses the new Google Maps JavaScript API v3. It will even do the geocoding for you!
JavaScript
7
star
45

metrics

A tool for tracking arbitrary metrics via Slack
Ruby
6
star
46

capybara-ui

Page objects for readable, resilient acceptance tests
Ruby
6
star
47

rubymotion-drawing

Quick and dirty drawing app written with RubyMotion
Ruby
6
star
48

rails_relay_authentication

Ruby
5
star
49

statsite-instrumental

Statsite Sink for Instrumental
Go
5
star
50

audit-demo

Demo application for acts_as_audited
5
star
51

migration_test_helper

Ruby
5
star
52

hourglass

Client and internal time management with Harvest
Ruby
5
star
53

acts_as_audited

acts_as_audited is now… Audited.
5
star
54

imap_authenticatable

Authenticate your Rails app using any IMAP server!
Ruby
5
star
55

rosie

CoffeeScript
4
star
56

playing-with-sunspot

A demo of sunspot and solr
Ruby
4
star
57

perfecttime

Mike West's PerfectTime.js, with a few updates.
JavaScript
4
star
58

ember-helpers

A collection of handlebars helpers for Ember.js
JavaScript
4
star
59

git-access

Secure access to hosted git repositories
Go
4
star
60

pivotalharvest

Ruby
4
star
61

pgbackups_archive_app

A very simple app to archive PGBackups to S3.
Ruby
4
star
62

recursable

Some helpers for using trees in Rails
Ruby
3
star
63

integrity-nabaztag

An Integrity notifier for Nabaztag
Ruby
3
star
64

adapter-simpledb

An adapter for Amazon's SimpleDB
Ruby
3
star
65

data-loss

Tracking when things happened.
Ruby
3
star
66

eharbor

Example Rails application for Ruby on Rails training used by Collective Idea and Idea Foundry (http://ideafoundry.info/ruby-on-rails). Note: we often use interactive rebases, so commit dates may not make sense.
Ruby
3
star
67

ios-swifter-example

Using Swifter to stub network calls
Swift
3
star
68

test-kitchen-provisioners

A collection of test-kitchen provisioners (https://github.com/opscode/test-kitchen)
Ruby
2
star
69

protoc-gen-twirp_ruby

A protoc plugin, written in Ruby, for generating Twirp-Ruby clients and/or services.
Ruby
2
star
70

twitter

A Twitter clone used for training
Ruby
2
star
71

collective-data

Gem for pulling data from the CollectiveData website
Ruby
2
star
72

get-to-work-go

Start and stop project specific, annotated Harvest timers with information from Pivotal Tracker
Go
2
star
73

dm-mongo-adapter

2
star
74

example_of_sunspot_test

A rails 3 codebase showing the usage of sunspot_test
Ruby
2
star
75

over_board

Ruby
2
star
76

namecase

Ruby
2
star
77

jquery.defaulttext

jQuery plugin to set the default text of an input using the title element
JavaScript
2
star
78

sunspot-indexing-strategies

A Rails 3 codebase that uses Sunspot to show how you can search search within words.
Ruby
2
star
79

mephisto-comment-notification

A simple comment notification plugin for the Mephisto blogging engine.
Ruby
2
star
80

mintastic

A Mint to QIF converter that also functions as a Rails + React + Redux tutorial app
Ruby
2
star
81

react-ujs-rails

React UJS package for rails, extracted from react-rails
JavaScript
1
star
82

mephisto_atompub

AtomPub plugin for mephisto
Ruby
1
star
83

donuts-android

Android client for donuts.collectiveidea.com
Kotlin
1
star
84

cucumber-web

Reusable web steps for Cucumber and Capybara
Ruby
1
star
85

cucumber_slices

Cucumber steps that we use often
Ruby
1
star
86

laketown

Calculate what you could save on internet service in Laketown Township
HTML
1
star
87

donuts

Collective Idea Donut Tracker
Ruby
1
star
88

donuts-ios

iOS Client for donuts.collectiveidea.com
Swift
1
star
89

build-test

Stupid simple way to test a continuous integration build server.
Shell
1
star
90

rubocop-config

Working toward a rubocop config we all can agree on.
1
star
91

no-phone

Not a phone.
Ruby
1
star
92

get_to_work

A rubygem to tag your Harvest time entries with Pivotal Tracker Information
Ruby
1
star
93

delayed_job_example

An example app for using Delayed Job
Ruby
1
star
94

finish_weekend

Finish Weekend
Ruby
1
star
95

twirp-rails

Make serving a Twirp RPC Services as easy and familiar as Rails controllers.
Ruby
1
star