#96 Auditing with Paper Trail
9/4/2017

Summary

Using the paper_trail gem, track changes to model records for auditing purposes and rollback changes when required.
6
rails database audit 6:30 min

Summary

Gemfilegem 'paper_trail'
Terminalrails g papertrail:install
rails db:migrate
config/initializers/paper_trail.rbPaperTrail.config.track_associations = false
PaperTrail.config.version_limit = 3
PaperTrail.serializer = PaperTrail::Serializers::JSON

PaperTrail::Version.class_eval do
  def changed_object
    @changed_object ||= JSON.parse(self.object, object_class: OpenStruct)
  end
end
user.rbclass User < ApplicationRecord
  has_paper_trail on: [:update, :destroy], only: [:first_name, :last_name]
end
show.html.erb

<h2>Versions</h2> <table class='table'>   <thead>     <tr>       <th>ID</th>       <th>Modifier</th>       <th>Action</th>       <th>Changes</th>     </tr>   </thead>   <tbody>     <% @user.versions.each do |version| %>       <%= tag.tr do %>         <%= tag.td version.id %>         <%= tag.td version.whodunnit %>         <%= tag.td link_to 'rollback', user_rollback_path(@user, version: version) %>         <%= tag.td do %>           <%= tag.ul class: 'list-group' do %>             <li class='list-group-item'>               <strong>First Name:</strong>                <%= version.changed_object.first_name %>             </li>             <li class='list-group-item'>               <strong>Last Name:</strong>                <%= version.changed_object.last_name %>             </li>             <li class='list-group-item'>               <strong>Email:</strong>                <%= version.changed_object.email %>             </li>           <% end %>         <% end %>       <% end %>     <% end %> </table>

application_controller.rbclass ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :set_paper_trail_whodunnit

  def user_for_paper_trail
    # user_signed_in? ? current_user.id : 'Public user'
    'Public user'
  end
end
routes.rbRails.application.routes.draw do
  resources :users do
    get :rollback
  end
  root to: 'users#index'
end
users_controller.rb  def rollback
    @user = User.find(params[:user_id])
    version = @user.versions.find(params[:version])
    if version.reify.save
      redirect_to @user, notice: 'User was successfully rollbacked.'
    else
      render :show
    end
  end