Audited Documentation

repository·main·Indexed 25 days ago

https://github.com/collectiveidea/audited

An ActiveRecord extension that logs all changes to models, including who made the changes, comments, and associations with related models. It tracks create, update, touch, and destroy actions, providing tools to retrieve model revisions, undo changes, and configure attribute-level auditing via options like :only, :except, and :redacted.

Tokens
3.9K
Snippets
9
Records
31
Agent score
77%

What's inside Audited

  1. Basic Usage of Audited

    main

    To enable auditing on an ActiveRecord model, call the audited method within the class definition. By default, Audited tracks create, update, touch (Rails 6+), and destroy actions, recording what changed in the audited_changes hash.

    class User < ActiveRecord::Base
      audited
    end
    
    # Usage
    user = User.create!(name: "Steve")
    user.update!(name: "Ryan")
    
    audit = user.audits.last
    puts audit.action           # => "update"
    puts audit.audited_changes # => {"name"=>["Steve", "Ryan"]}
  2. Install Audited

    main

    Add audited to your Gemfile. If you are using require: false, you must manually initialize it in a Rails initializer.

    To set up the necessary audits table, run the installation generator and migrate your database. You can customize the column types for changes (e.g., using jsonb for PostgreSQL or json for MySQL) and the user_id column (e.g., for UUIDs) during installation.

    If you are upgrading from an older version of Audited, run the upgrade generator to ensure all required columns are present.

  3. Enable auditing on an ActiveRecord model

    main

    Use the audited method within an ActiveRecord model to track changes (create, update, destroy) in an audit table. By default, it audits all columns except for internal metadata like primary keys and timestamps.

    To add a comment to an audit record, set the audit_comment attribute on the model instance before performing the operation.

    class User < ActiveRecord::Base
      audited
    end
  4. Conditional Auditing

    main

    You can use :if and :unless options (similar to ActiveModel callbacks) to determine if a model should be audited.

    class User < ActiveRecord::Base
      # Audit only if the user is active
      audited if: :active?
    
      # Audit unless a specific condition is met via Proc
      audited unless: Proc.new { |u| u.ninja? }
    
      def active?
        last_login > 6.months.ago
      end
    end
  5. Disable Auditing

    main

    Audited provides several ways to temporarily or permanently disable auditing:

    • On a specific save: Use @model.save_without_auditing or @model.without_auditing { @model.save }.
    • On specific columns: Set Model.non_audited_columns = [:col1, :col2].
    • On an entire model: Set Model.auditing_enabled = false.
    • Globally: Set Audited.auditing_enabled = false.

    To re-enable auditing on a model that has it disabled by default, use @model.save_with_auditing or @model.with_auditing { @model.save }.

    # Disable for a single save block
    @user.without_auditing do
      @user.save
    end
    
    # Disable auditing for specific columns on a model
    User.non_audited_columns = [:first_name, :last_name]
    
    # Disable auditing for an entire model
    User.auditing_enabled = false
    
    # Re-enable auditing temporarily
    User.auditing_enabled = false
    @user.with_auditing do
      @user.save
    end
  6. Track Current User

    main

    In a Rails request, Audited automatically attributes changes to the current_user method in your controller.

    Customizing the user method: Set Audited.current_user_method = :your_method in an initializer.

    Manual User Attribution (Outside Requests): Use Audited::Audit.as_user(user) { ... } to wrap blocks of code where you want to specify the auditor. This accepts both ActiveRecord objects and strings (useful for CLI/background jobs).

    CLI/Global User Setting: You can also set a global user for the current thread using Audited.store[:audited_user] = user.

  7. Configure Audited Columns and Callbacks

    main

    You can restrict which attributes are audited or which lifecycle events trigger an audit using options passed to the audited method.

    Column Options:

    • audited: Audit all fields (default).
    • audited only: :column_name: Audit only a specific column.
    • audited only: [:col1, :col2]: Audit a specific list of columns.
    • audited except: :column_name: Audit everything except the specified column.

    Callback Options:

    • audited only: :column_name, on: [:action1, :action2]: Audit specific columns only during specific actions (e.g., [:update, :destroy]).

    You can also globally ignore default callbacks in an initializer using Audited.ignored_default_callbacks = [:action].

    class User < ActiveRecord::Base
      # Audit only specific columns for specific actions
      audited only: :name, on: [:update, :destroy]
    
      # Audit everything except password
      # audited except: :password
    end
  8. Custom Audit Model

    main

    If you need to extend the functionality of the audit records themselves, you can create a custom class inheriting from Audited::Audit and configure it in an initializer.

    # 1. Define custom class
    class CustomAudit < Audited::Audit
      def some_custom_behavior
        "Hiya!"
      end
    end
    
    # 2. Configure in config/initializers/audited.rb
    Audited.config do |config|
      config.audit_class = "CustomAudit"
    end
  9. Associate Audits with Other Models

    main

    You can link audits to a parent model using the :associated_with option. This allows you to retrieve all audits for a group of related models (e.g., all audits for all users belonging to a specific company).

    class User < ActiveRecord::Base
      belongs_to :company
      audited associated_with: :company
    end
    
    class Company < ActiveRecord::Base
      has_many :users
      audited
      has_associated_audits
    end
    
    # Accessing audits
    company.associated_audits.last.auditable # => returns the User
    company.own_and_associated_audits      # returns both