audited-hp 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +32 -0
- data/.yardopts +3 -0
- data/Appraisals +22 -0
- data/CHANGELOG +153 -0
- data/Gemfile +3 -0
- data/LICENSE +19 -0
- data/README.md +299 -0
- data/Rakefile +18 -0
- data/gemfiles/rails40.gemfile +9 -0
- data/gemfiles/rails41.gemfile +8 -0
- data/gemfiles/rails42.gemfile +8 -0
- data/gemfiles/rails50.gemfile +8 -0
- data/lib/audited-rspec.rb +4 -0
- data/lib/audited.rb +29 -0
- data/lib/audited/audit.rb +149 -0
- data/lib/audited/auditor.rb +309 -0
- data/lib/audited/rspec_matchers.rb +177 -0
- data/lib/audited/sweeper.rb +60 -0
- data/lib/audited/version.rb +3 -0
- data/lib/generators/audited/install_generator.rb +20 -0
- data/lib/generators/audited/migration.rb +15 -0
- data/lib/generators/audited/templates/add_association_to_audits.rb +11 -0
- data/lib/generators/audited/templates/add_comment_to_audits.rb +9 -0
- data/lib/generators/audited/templates/add_remote_address_to_audits.rb +10 -0
- data/lib/generators/audited/templates/add_request_uuid_to_audits.rb +10 -0
- data/lib/generators/audited/templates/install.rb +30 -0
- data/lib/generators/audited/templates/rename_association_to_associated.rb +23 -0
- data/lib/generators/audited/templates/rename_changes_to_audited_changes.rb +9 -0
- data/lib/generators/audited/templates/rename_parent_to_association.rb +11 -0
- data/lib/generators/audited/upgrade_generator.rb +57 -0
- data/spec/audited/audit_spec.rb +199 -0
- data/spec/audited/auditor_spec.rb +607 -0
- data/spec/audited/sweeper_spec.rb +106 -0
- data/spec/audited_spec_helpers.rb +20 -0
- data/spec/rails_app/config/application.rb +8 -0
- data/spec/rails_app/config/database.yml +24 -0
- data/spec/rails_app/config/environment.rb +5 -0
- data/spec/rails_app/config/environments/development.rb +21 -0
- data/spec/rails_app/config/environments/production.rb +35 -0
- data/spec/rails_app/config/environments/test.rb +47 -0
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_app/config/initializers/inflections.rb +2 -0
- data/spec/rails_app/config/initializers/secret_token.rb +3 -0
- data/spec/rails_app/config/routes.rb +3 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/active_record/models.rb +99 -0
- data/spec/support/active_record/schema.rb +81 -0
- data/test/db/version_1.rb +17 -0
- data/test/db/version_2.rb +18 -0
- data/test/db/version_3.rb +19 -0
- data/test/db/version_4.rb +20 -0
- data/test/db/version_5.rb +18 -0
- data/test/db/version_6.rb +17 -0
- data/test/install_generator_test.rb +17 -0
- data/test/test_helper.rb +19 -0
- data/test/upgrade_generator_test.rb +77 -0
- metadata +229 -0
@@ -0,0 +1,106 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class AuditsController < ActionController::Base
|
4
|
+
attr_reader :company
|
5
|
+
|
6
|
+
def create
|
7
|
+
@company = Models::ActiveRecord::Company.create
|
8
|
+
head :ok
|
9
|
+
end
|
10
|
+
|
11
|
+
def update
|
12
|
+
current_user.update_attributes(password: 'foo')
|
13
|
+
head :ok
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_accessor :current_user
|
19
|
+
attr_accessor :custom_user
|
20
|
+
end
|
21
|
+
|
22
|
+
describe AuditsController do
|
23
|
+
include RSpec::Rails::ControllerExampleGroup
|
24
|
+
render_views
|
25
|
+
|
26
|
+
before(:each) do
|
27
|
+
Audited.current_user_method = :current_user
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:user) { create_user }
|
31
|
+
|
32
|
+
describe "POST audit" do
|
33
|
+
|
34
|
+
it "should audit user" do
|
35
|
+
controller.send(:current_user=, user)
|
36
|
+
expect {
|
37
|
+
post :create
|
38
|
+
}.to change( Audited::Audit, :count )
|
39
|
+
|
40
|
+
expect(controller.company.audits.last.user).to eq(user)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should support custom users for sweepers" do
|
44
|
+
controller.send(:custom_user=, user)
|
45
|
+
Audited.current_user_method = :custom_user
|
46
|
+
|
47
|
+
expect {
|
48
|
+
post :create
|
49
|
+
}.to change( Audited::Audit, :count )
|
50
|
+
|
51
|
+
expect(controller.company.audits.last.user).to eq(user)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should record the remote address responsible for the change" do
|
55
|
+
request.env['REMOTE_ADDR'] = "1.2.3.4"
|
56
|
+
controller.send(:current_user=, user)
|
57
|
+
|
58
|
+
post :create
|
59
|
+
|
60
|
+
expect(controller.company.audits.last.remote_address).to eq('1.2.3.4')
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should record a UUID for the web request responsible for the change" do
|
64
|
+
allow_any_instance_of(ActionDispatch::Request).to receive(:uuid).and_return("abc123")
|
65
|
+
controller.send(:current_user=, user)
|
66
|
+
|
67
|
+
post :create
|
68
|
+
|
69
|
+
expect(controller.company.audits.last.request_uuid).to eq("abc123")
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "PUT update" do
|
75
|
+
it "should not save blank audits" do
|
76
|
+
controller.send(:current_user=, user)
|
77
|
+
|
78
|
+
expect {
|
79
|
+
put :update, id: 123
|
80
|
+
}.to_not change( Audited::Audit, :count )
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
describe Audited::Sweeper do
|
87
|
+
|
88
|
+
it "should be thread-safe" do
|
89
|
+
t1 = Thread.new do
|
90
|
+
sleep 0.5
|
91
|
+
Audited::Sweeper.instance.controller = 'thread1 controller instance'
|
92
|
+
expect(Audited::Sweeper.instance.controller).to eq('thread1 controller instance')
|
93
|
+
end
|
94
|
+
|
95
|
+
t2 = Thread.new do
|
96
|
+
Audited::Sweeper.instance.controller = 'thread2 controller instance'
|
97
|
+
sleep 1
|
98
|
+
expect(Audited::Sweeper.instance.controller).to eq('thread2 controller instance')
|
99
|
+
end
|
100
|
+
|
101
|
+
t1.join; t2.join
|
102
|
+
|
103
|
+
expect(Audited::Sweeper.instance.controller).to be_nil
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module AuditedSpecHelpers
|
2
|
+
|
3
|
+
def create_user(attrs = {})
|
4
|
+
Models::ActiveRecord::User.create({name: 'Brandon', username: 'brandon', password: 'password'}.merge(attrs))
|
5
|
+
end
|
6
|
+
|
7
|
+
def build_user(attrs = {})
|
8
|
+
Models::ActiveRecord::User.new({name: 'darth', username: 'darth', password: 'noooooooo'}.merge(attrs))
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_versions(n = 2)
|
12
|
+
Models::ActiveRecord::User.create(name: 'Foobar 1').tap do |u|
|
13
|
+
(n - 1).times do |i|
|
14
|
+
u.update_attribute :name, "Foobar #{i + 2}"
|
15
|
+
end
|
16
|
+
u.reload
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
sqlite3mem: &SQLITE3MEM
|
2
|
+
adapter: sqlite3
|
3
|
+
database: ":memory:"
|
4
|
+
|
5
|
+
sqlite3: &SQLITE
|
6
|
+
adapter: sqlite3
|
7
|
+
database: audited_test.sqlite3.db
|
8
|
+
|
9
|
+
postgresql: &POSTGRES
|
10
|
+
adapter: postgresql
|
11
|
+
username: postgres
|
12
|
+
password:
|
13
|
+
database: audited_test
|
14
|
+
min_messages: ERROR
|
15
|
+
|
16
|
+
mysql: &MYSQL
|
17
|
+
adapter: mysql2
|
18
|
+
host: localhost
|
19
|
+
username: root
|
20
|
+
password:
|
21
|
+
database: audited_test
|
22
|
+
|
23
|
+
test:
|
24
|
+
<<: *<%= ENV['DB'] || 'SQLITE3MEM' %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
RailsApp::Application.configure do
|
2
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
3
|
+
|
4
|
+
# In the development environment your application's code is reloaded on
|
5
|
+
# every request. This slows down response time but is perfect for development
|
6
|
+
# since you don't have to restart the webserver when you make code changes.
|
7
|
+
config.cache_classes = false
|
8
|
+
|
9
|
+
# Log error messages when you accidentally call methods on nil.
|
10
|
+
# config.whiny_nils = true
|
11
|
+
|
12
|
+
# Show full error reports and disable caching
|
13
|
+
config.consider_all_requests_local = true
|
14
|
+
config.action_view.debug_rjs = true
|
15
|
+
config.action_controller.perform_caching = false
|
16
|
+
|
17
|
+
# Don't care if the mailer can't send
|
18
|
+
config.action_mailer.raise_delivery_errors = false
|
19
|
+
|
20
|
+
config.eager_load = false
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
RailsApp::Application.configure do
|
2
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
3
|
+
|
4
|
+
# The production environment is meant for finished, "live" apps.
|
5
|
+
# Code is not reloaded between requests
|
6
|
+
config.cache_classes = true
|
7
|
+
|
8
|
+
# Full error reports are disabled and caching is turned on
|
9
|
+
config.consider_all_requests_local = false
|
10
|
+
config.action_controller.perform_caching = true
|
11
|
+
|
12
|
+
# See everything in the log (default is :info)
|
13
|
+
# config.log_level = :debug
|
14
|
+
|
15
|
+
# Use a different logger for distributed setups
|
16
|
+
# config.logger = SyslogLogger.new
|
17
|
+
|
18
|
+
# Use a different cache store in production
|
19
|
+
# config.cache_store = :mem_cache_store
|
20
|
+
|
21
|
+
# Disable Rails's static asset server
|
22
|
+
# In production, Apache or nginx will already do this
|
23
|
+
config.serve_static_assets = false
|
24
|
+
|
25
|
+
# Enable serving of images, stylesheets, and javascripts from an asset server
|
26
|
+
# config.action_controller.asset_host = "http://assets.example.com"
|
27
|
+
|
28
|
+
# Disable delivery errors, bad email addresses will be ignored
|
29
|
+
# config.action_mailer.raise_delivery_errors = false
|
30
|
+
|
31
|
+
# Enable threaded mode
|
32
|
+
# config.threadsafe!
|
33
|
+
|
34
|
+
config.eager_load = true
|
35
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
RailsApp::Application.configure do
|
2
|
+
# Settings specified here will take precedence over those in config/application.rb.
|
3
|
+
|
4
|
+
# The test environment is used exclusively to run your application's
|
5
|
+
# test suite. You never need to work with it otherwise. Remember that
|
6
|
+
# your test database is "scratch space" for the test suite and is wiped
|
7
|
+
# and recreated between test runs. Don't rely on the data there!
|
8
|
+
config.cache_classes = true
|
9
|
+
|
10
|
+
# Do not eager load code on boot. This avoids loading your whole application
|
11
|
+
# just for the purpose of running a single test. If you are using a tool that
|
12
|
+
# preloads Rails for running tests, you may have to set it to true.
|
13
|
+
config.eager_load = false
|
14
|
+
|
15
|
+
# Configure static file server for tests with Cache-Control for performance.
|
16
|
+
if config.respond_to?(:public_file_server)
|
17
|
+
config.public_file_server.enabled = true
|
18
|
+
config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
|
19
|
+
else
|
20
|
+
config.static_cache_control = 'public, max-age=3600'
|
21
|
+
config.serve_static_files = true
|
22
|
+
end
|
23
|
+
|
24
|
+
# Show full error reports and disable caching.
|
25
|
+
config.consider_all_requests_local = true
|
26
|
+
# config.action_controller.perform_caching = false
|
27
|
+
|
28
|
+
# Raise exceptions instead of rendering exception templates.
|
29
|
+
config.action_dispatch.show_exceptions = false
|
30
|
+
|
31
|
+
# Disable request forgery protection in test environment.
|
32
|
+
# config.action_controller.allow_forgery_protection = false
|
33
|
+
|
34
|
+
# Tell Action Mailer not to deliver emails to the real world.
|
35
|
+
# The :test delivery method accumulates sent emails in the
|
36
|
+
# ActionMailer::Base.deliveries array.
|
37
|
+
config.action_mailer.delivery_method = :test
|
38
|
+
|
39
|
+
# Randomize the order test cases are executed.
|
40
|
+
config.active_support.test_order = :random
|
41
|
+
|
42
|
+
# Print deprecation notices to the stderr.
|
43
|
+
config.active_support.deprecation = :stderr
|
44
|
+
|
45
|
+
# Raises error for missing translations
|
46
|
+
# config.action_view.raise_on_missing_translations = true
|
47
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
|
4
|
+
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
|
5
|
+
|
6
|
+
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
|
7
|
+
Rails.backtrace_cleaner.remove_silencers!
|
@@ -0,0 +1,3 @@
|
|
1
|
+
Rails.application.config.secret_token = 'ea942c41850d502f2c8283e26bdc57829f471bb18224ddff0a192c4f32cdf6cb5aa0d82b3a7a7adbeb640c4b06f3aa1cd5f098162d8240f669b39d6b49680571'
|
2
|
+
Rails.application.config.session_store :cookie_store, key: "_my_app"
|
3
|
+
Rails.application.config.secret_key_base = 'secret value'
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
2
|
+
|
3
|
+
if Bundler.definition.dependencies.map(&:name).include?('protected_attributes')
|
4
|
+
require 'protected_attributes'
|
5
|
+
end
|
6
|
+
require 'rails_app/config/environment'
|
7
|
+
require 'rspec/rails'
|
8
|
+
require 'audited'
|
9
|
+
require 'audited_spec_helpers'
|
10
|
+
require 'support/active_record/models'
|
11
|
+
load "audited/sweeper.rb" # force to reload sweeper
|
12
|
+
|
13
|
+
SPEC_ROOT = Pathname.new(File.expand_path('../', __FILE__))
|
14
|
+
|
15
|
+
Dir[SPEC_ROOT.join('support/*.rb')].each{|f| require f }
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.include AuditedSpecHelpers
|
19
|
+
config.use_transactional_fixtures = false if Rails.version.start_with?('4.')
|
20
|
+
config.use_transactional_tests = false if config.respond_to?(:use_transactional_tests=)
|
21
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require File.expand_path('../schema', __FILE__)
|
3
|
+
|
4
|
+
module Models
|
5
|
+
module ActiveRecord
|
6
|
+
class User < ::ActiveRecord::Base
|
7
|
+
audited allow_mass_assignment: true, except: :password
|
8
|
+
|
9
|
+
attr_protected :logins if respond_to?(:attr_protected)
|
10
|
+
|
11
|
+
def name=(val)
|
12
|
+
write_attribute(:name, CGI.escapeHTML(val))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class UserOnlyPassword < ::ActiveRecord::Base
|
17
|
+
self.table_name = :users
|
18
|
+
audited allow_mass_assignment: true, only: :password
|
19
|
+
end
|
20
|
+
|
21
|
+
class CommentRequiredUser < ::ActiveRecord::Base
|
22
|
+
self.table_name = :users
|
23
|
+
audited comment_required: true
|
24
|
+
end
|
25
|
+
|
26
|
+
class AccessibleAfterDeclarationUser < ::ActiveRecord::Base
|
27
|
+
self.table_name = :users
|
28
|
+
audited
|
29
|
+
attr_accessible :name, :username, :password if respond_to?(:attr_accessible)
|
30
|
+
end
|
31
|
+
|
32
|
+
class AccessibleBeforeDeclarationUser < ::ActiveRecord::Base
|
33
|
+
self.table_name = :users
|
34
|
+
attr_accessible :name, :username, :password if respond_to?(:attr_accessible) # declare attr_accessible before calling aaa
|
35
|
+
audited
|
36
|
+
end
|
37
|
+
|
38
|
+
class NoAttributeProtectionUser < ::ActiveRecord::Base
|
39
|
+
self.table_name = :users
|
40
|
+
audited allow_mass_assignment: true
|
41
|
+
end
|
42
|
+
|
43
|
+
class UserWithAfterAudit < ::ActiveRecord::Base
|
44
|
+
self.table_name = :users
|
45
|
+
audited
|
46
|
+
attr_accessor :bogus_attr, :around_attr
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def after_audit
|
51
|
+
self.bogus_attr = "do something"
|
52
|
+
end
|
53
|
+
|
54
|
+
def around_audit
|
55
|
+
self.around_attr = yield
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Company < ::ActiveRecord::Base
|
60
|
+
audited
|
61
|
+
end
|
62
|
+
|
63
|
+
class Company::STICompany < Company
|
64
|
+
end
|
65
|
+
|
66
|
+
class Owner < ::ActiveRecord::Base
|
67
|
+
self.table_name = 'users'
|
68
|
+
has_associated_audits
|
69
|
+
has_many :companies, class_name: "OwnedCompany", dependent: :destroy
|
70
|
+
end
|
71
|
+
|
72
|
+
class OwnedCompany < ::ActiveRecord::Base
|
73
|
+
self.table_name = 'companies'
|
74
|
+
belongs_to :owner, class_name: "Owner"
|
75
|
+
attr_accessible :name, :owner if respond_to?(:attr_accessible) # declare attr_accessible before calling aaa
|
76
|
+
audited associated_with: :owner
|
77
|
+
end
|
78
|
+
|
79
|
+
class OnUpdateDestroy < ::ActiveRecord::Base
|
80
|
+
self.table_name = 'companies'
|
81
|
+
audited on: [:update, :destroy]
|
82
|
+
end
|
83
|
+
|
84
|
+
class OnCreateDestroy < ::ActiveRecord::Base
|
85
|
+
self.table_name = 'companies'
|
86
|
+
audited on: [:create, :destroy]
|
87
|
+
end
|
88
|
+
|
89
|
+
class OnCreateDestroyExceptName < ::ActiveRecord::Base
|
90
|
+
self.table_name = 'companies'
|
91
|
+
audited except: :name, on: [:create, :destroy]
|
92
|
+
end
|
93
|
+
|
94
|
+
class OnCreateUpdate < ::ActiveRecord::Base
|
95
|
+
self.table_name = 'companies'
|
96
|
+
audited on: [:create, :update]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
begin
|
5
|
+
db_config = ActiveRecord::Base.configurations[Rails.env].clone
|
6
|
+
db_type = db_config['adapter']
|
7
|
+
db_name = db_config.delete('database')
|
8
|
+
raise Exception.new('No database name specified.') if db_name.blank?
|
9
|
+
if db_type == 'sqlite3'
|
10
|
+
db_file = Pathname.new(__FILE__).dirname.join(db_name)
|
11
|
+
db_file.unlink if db_file.file?
|
12
|
+
else
|
13
|
+
if defined?(JRUBY_VERSION)
|
14
|
+
db_config.symbolize_keys!
|
15
|
+
db_config[:configure_connection] = false
|
16
|
+
end
|
17
|
+
adapter = ActiveRecord::Base.send("#{db_type}_connection", db_config)
|
18
|
+
adapter.recreate_database db_name
|
19
|
+
adapter.disconnect!
|
20
|
+
end
|
21
|
+
rescue Exception => e
|
22
|
+
Kernel.warn e
|
23
|
+
end
|
24
|
+
|
25
|
+
logfile = Pathname.new(__FILE__).dirname.join('debug.log')
|
26
|
+
logfile.unlink if logfile.file?
|
27
|
+
ActiveRecord::Base.logger = Logger.new(logfile)
|
28
|
+
|
29
|
+
ActiveRecord::Migration.verbose = false
|
30
|
+
ActiveRecord::Base.establish_connection
|
31
|
+
|
32
|
+
ActiveRecord::Schema.define do
|
33
|
+
create_table :users do |t|
|
34
|
+
t.column :name, :string
|
35
|
+
t.column :username, :string
|
36
|
+
t.column :password, :string
|
37
|
+
t.column :activated, :boolean
|
38
|
+
t.column :suspended_at, :datetime
|
39
|
+
t.column :logins, :integer, default: 0
|
40
|
+
t.column :created_at, :datetime
|
41
|
+
t.column :updated_at, :datetime
|
42
|
+
end
|
43
|
+
|
44
|
+
create_table :companies do |t|
|
45
|
+
t.column :name, :string
|
46
|
+
t.column :owner_id, :integer
|
47
|
+
t.column :type, :string
|
48
|
+
end
|
49
|
+
|
50
|
+
create_table :authors do |t|
|
51
|
+
t.column :name, :string
|
52
|
+
end
|
53
|
+
|
54
|
+
create_table :books do |t|
|
55
|
+
t.column :authord_id, :integer
|
56
|
+
t.column :title, :string
|
57
|
+
end
|
58
|
+
|
59
|
+
create_table :audits do |t|
|
60
|
+
t.column :auditable_id, :integer
|
61
|
+
t.column :auditable_type, :string
|
62
|
+
t.column :associated_id, :integer
|
63
|
+
t.column :associated_type, :string
|
64
|
+
t.column :user_id, :integer
|
65
|
+
t.column :user_type, :string
|
66
|
+
t.column :username, :string
|
67
|
+
t.column :action, :string
|
68
|
+
t.column :audited_changes, :text
|
69
|
+
t.column :version, :integer, default: 0
|
70
|
+
t.column :comment, :string
|
71
|
+
t.column :remote_address, :string
|
72
|
+
t.column :request_uuid, :string
|
73
|
+
t.column :created_at, :datetime
|
74
|
+
end
|
75
|
+
|
76
|
+
add_index :audits, [:auditable_id, :auditable_type], name: 'auditable_index'
|
77
|
+
add_index :audits, [:associated_id, :associated_type], name: 'associated_index'
|
78
|
+
add_index :audits, [:user_id, :user_type], name: 'user_index'
|
79
|
+
add_index :audits, :request_uuid
|
80
|
+
add_index :audits, :created_at
|
81
|
+
end
|