Changed

Gem Version

A gem for tracking what changed when.

Installation

Add this line to your application's Gemfile:

gem 'changed'

And then execute:

$ bundle

Or install it yourself as:

$ gem install changed

After installing the gem run the following to setup:

rails changed:install:migrations
rails db:migrate

Usage

This gem is designed to integrate with active record objects:

class Employee
  include Changed::Auditable
  belongs_to :company

  audited :name, :email, :eid, :company, transformations: { eid: 'Employee ID' }
end

To ensure the proper 'changer' is tracked, add the following code to your application controller:

before_action :configure_audit_changer

protected

def configure_audit_changer
  Changed.changer = User.current
end

To execute code with a different timestamp or changer, use the following:

employee = Employee.find_by(name: "...")
Changed.perform(changer: User.current, timestamp: Time.now) do
  employee.name = "..."
  employee.save!
end

Fields

Fields (i.e. name, email, phone, etc) are tracked inside the changeset key of a generated audit. They can be queried using:

SELECT
  "audits"."timestamp",
  "audits"."changeset"->'name'->>0 AS "was",
  "audits"."changeset"->'name'->>1 AS "now",
  "changers"."name" AS "changer"
FROM "audits"
JOIN "users" AS "changers" ON "audits"."changer_id" = "changers"."id" AND "audits"."changer_type" = 'User'
WHERE "audits"."changeset"->>'name' IS NOT NULL

Associations

Associations (i.e. user, favourites, etc) are tracked by the associations table. They can be queried using:

SELECT
  "audits"."timestamp",
  "changers"."name" AS "changer",
  CASE "associations"."kind"
  WHEN '0' THEN 'ADD'
  WHEN '1' THEN 'REMOVE'
  END AS "kind",
  "users"."name" AS "user"
FROM "audits"
JOIN "associations" ON "associations"."audit_id" = "audits"."id"
JOIN "users" ON "associations"."associated_id" = "users"."id" AND "associations"."associated_type" = 'User'
JOIN "users" AS "changers" ON "audits"."changer_id" = "changers"."id" AND "audits"."changer_type" = 'User'
WHERE "associations"."name" = 'user'

Configuration

Specifying default_changer_proc gives a changer if one cannot be inferred otherwise:

Changed.config.default_changer_proc = ->{ User.system }

Status

CircleCI

License

The gem is available as open source under the terms of the MIT License.