Articles tagged with acts_as_audited
Several people have reported that acts_as_audited does not work with ActiveScaffold. I don’t use ActiveScaffold, so I had no motivation to fix it. But thanks to a tip from Aaron, this has now been fixed.
To make acts_as_audited work with ActiveScaffold, only enable auditing for only the :create, :update, and :destroy actions.
class ApplicationController < ActionController::Base
audit User, Thing, :only => [:create, :update, :destroy]
end
I’m not sure exactly why it breaks or why this fixes it, but from this thread it sounds like ActiveScaffold just doesn’t support polymorphic associations, which is what acts_as_audited uses to associated audits with models.
When I first created acts_as_audited over a year ago, I intended to add versioning/revisioning capabilities, but found I never really had a need. Well, it just so happened that I finally had a need on an app that we are working on. So, acts_as_audited now allows you to revert back to previous revisions.
You can get all the revisions of a model:
article.revisions.each |revision|
puts revision.class #=> Article
puts revision.version #=> 7, 6, 5, 4...
end
or a specific revision:
revision = article.revision(5)
puts revision.title #=> "Old Title"
or the previous revision. Reverting is as simple as saving a revision:
previous = article.revision(:previous)
previous.save # revert to previous revision
See the original post for more details about installing and using the plugin.
How is this different from acts_as_versioned?
I’ve never used acts_as_versioned1 (because I’ve never had a need to do versioning), but I do know that it has a few annoying limitations: 1) it requires a separate table (and model) for each model that you want to version, and 2) it saves every attribute, even if it’s not changed.
acts_as_audited already stories all the changes (and only the changes) in one table, so adding versioning was rather trivial. Revisions are created by walking backward through the audits, collecting the changes, and returning an instance of the model.
Upgrading
To use the versioning support, you must add a version field in the audits table:
add_column :audits, :version, :integer, :default => 0
Note: if you already have audit records, the version field will have to be initialized.
Feedback
This code is fairly specific to what I needed, so if you’re using it, I would love to hear how it is working for you. Suggestions and patches welcome.
Thanks to Chaz for pointing out the section in the Rails Recipes book about using Rails’ cache_sweeper to implement auditing. I’ve updated acts_as_audited so that it can quickly and easily audit modifications to your models along with the user that made the change. Check out the original post for more information and examples of how to use it.
Thanks to Michael Schuerig for pointing out that malicious users could unassociate your audit records due to the use of has_many in acts_as_audited. has_many :audits creates an attribute accessor called audit_ids on the model objects that you declare acts_as_audited, which could allow users to pass an array of ids that would overwrite the actual audit records.
This has been fixed by adding attr_protected :audit_ids, which protects it from mass assignment. If you’re not using SVN externals, make sure you get the latest version.
acts_as_audited is an Active Record plugin that logs all modifications to your models in an
audits table. It uses a polymorphic association to store an audit record for any of the model objects that you wish to have audited. The audit log stores the model that the change was on, the “action” (create, update, destroy), a serialzied hash of the changes, and optionally the user that performed the action.
Auditing in Rails
NOTE: read the caveats section if the following isn’t working.
If you’re using acts_as_audited within Rails, you can simply declare which models should be audited. acts_as_audited can also automatically record the user that made the change if your controller has a current_user method.
class ApplicationController < ActionController::Base
audit User, List, Item
protected
def current_user
@user ||= User.find(session[:user])
end
end
Caveats
Auditing with user support depends on Rails’ caching mechanisms, therefore auditing isn’t enabled during development mode. To test that auditing is working, start up your app in production mode, or change the following options in config/environments/development.rb:
config.cache_classes = true
config.action_controller.perform_caching = true
Customizing
To get auditing outside of Rails, or to customize which fields are audited within Rails, you can explicitly declare acts_as_audited on your models. The :except option allows you to specify one or more attributes that you don’t want to be saved in the audit log.
class User < ActiveRecord::Base
acts_as_audited :except => [:password, :credit_card_number]
end
Installation
You can grab the plugin by running:
script/plugin install git://github.com/collectiveidea/acts_as_audited.git
Run the migration generator and migrate to add the audits table.
script/generate audited_migration add_audits_table
rake db:migrate
Upgrading
Those upgrading from version 0.2 need to add 2 fields the audits table:
add_column :audits, :user_type, :string
add_column :audits, :username, :string
posted by brandon
| updated June 19th 07:30 PM