audited 4.2.2 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of audited might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +10 -9
- data/Appraisals +10 -6
- data/Gemfile +1 -13
- data/README.md +46 -33
- data/Rakefile +3 -18
- data/gemfiles/rails40.gemfile +1 -5
- data/gemfiles/rails41.gemfile +1 -5
- data/gemfiles/rails42.gemfile +1 -5
- data/gemfiles/rails50.gemfile +8 -0
- data/lib/audited-rspec.rb +4 -0
- data/lib/audited.rb +15 -2
- data/lib/audited/audit.rb +97 -57
- data/lib/audited/auditor.rb +73 -45
- data/lib/audited/rspec_matchers.rb +6 -2
- data/lib/audited/sweeper.rb +12 -23
- data/lib/audited/version.rb +1 -1
- 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 +6 -22
- data/spec/rails_app/config/environments/test.rb +7 -4
- data/spec/rails_app/config/initializers/secret_token.rb +1 -1
- data/spec/rails_app/config/routes.rb +1 -4
- data/spec/spec_helper.rb +7 -9
- data/spec/support/active_record/models.rb +20 -13
- data/spec/support/active_record/schema.rb +36 -12
- data/test/db/version_1.rb +4 -4
- data/test/db/version_2.rb +4 -4
- data/test/db/version_3.rb +4 -4
- data/test/db/version_4.rb +4 -4
- data/test/db/version_5.rb +2 -2
- data/test/db/version_6.rb +2 -2
- data/test/install_generator_test.rb +1 -1
- data/test/upgrade_generator_test.rb +10 -10
- metadata +73 -37
- data/lib/audited/active_record/version.rb +0 -5
- data/lib/audited/mongo_mapper/version.rb +0 -5
- data/spec/support/mongo_mapper/connection.rb +0 -4
- data/spec/support/mongo_mapper/models.rb +0 -214
@@ -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
|
@@ -1,19 +1,15 @@
|
|
1
1
|
module AuditedSpecHelpers
|
2
2
|
|
3
|
-
def create_user(
|
4
|
-
|
5
|
-
klass.create({:name => 'Brandon', :username => 'brandon', :password => 'password'}.merge(attrs))
|
3
|
+
def create_user(attrs = {})
|
4
|
+
Models::ActiveRecord::User.create({name: 'Brandon', username: 'brandon', password: 'password'}.merge(attrs))
|
6
5
|
end
|
7
6
|
|
8
|
-
def build_user(
|
9
|
-
|
10
|
-
klass.new({:name => 'darth', :username => 'darth', :password => 'noooooooo'}.merge(attrs))
|
7
|
+
def build_user(attrs = {})
|
8
|
+
Models::ActiveRecord::User.new({name: 'darth', username: 'darth', password: 'noooooooo'}.merge(attrs))
|
11
9
|
end
|
12
10
|
|
13
|
-
def create_versions(n = 2
|
14
|
-
|
15
|
-
|
16
|
-
klass.create(:name => 'Foobar 1').tap do |u|
|
11
|
+
def create_versions(n = 2)
|
12
|
+
Models::ActiveRecord::User.create(name: 'Foobar 1').tap do |u|
|
17
13
|
(n - 1).times do |i|
|
18
14
|
u.update_attribute :name, "Foobar #{i + 2}"
|
19
15
|
end
|
@@ -21,16 +17,4 @@ module AuditedSpecHelpers
|
|
21
17
|
end
|
22
18
|
end
|
23
19
|
|
24
|
-
def create_active_record_user(attrs = {})
|
25
|
-
create_user(false, attrs)
|
26
|
-
end
|
27
|
-
|
28
|
-
def create_mongo_user(attrs = {})
|
29
|
-
create_user(true, attrs)
|
30
|
-
end
|
31
|
-
|
32
|
-
def create_mongo_versions(n = 2)
|
33
|
-
create_versions(n, true)
|
34
|
-
end
|
35
|
-
|
36
20
|
end
|
@@ -12,11 +12,14 @@ RailsApp::Application.configure do
|
|
12
12
|
# preloads Rails for running tests, you may have to set it to true.
|
13
13
|
config.eager_load = false
|
14
14
|
|
15
|
-
# Configure static asset server for tests with Cache-Control for performance.
|
16
|
-
config.serve_static_assets = true
|
17
15
|
# Configure static file server for tests with Cache-Control for performance.
|
18
|
-
config.
|
19
|
-
|
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
|
20
23
|
|
21
24
|
# Show full error reports and disable caching.
|
22
25
|
config.consider_all_requests_local = true
|
@@ -1,3 +1,3 @@
|
|
1
1
|
Rails.application.config.secret_token = 'ea942c41850d502f2c8283e26bdc57829f471bb18224ddff0a192c4f32cdf6cb5aa0d82b3a7a7adbeb640c4b06f3aa1cd5f098162d8240f669b39d6b49680571'
|
2
|
-
Rails.application.config.session_store :cookie_store, :
|
2
|
+
Rails.application.config.session_store :cookie_store, key: "_my_app"
|
3
3
|
Rails.application.config.secret_key_base = 'secret value'
|
@@ -1,6 +1,3 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
|
-
|
3
|
-
# This is a legacy wild controller route that's not recommended for RESTful applications.
|
4
|
-
# Note: This route will make all actions in every controller accessible via GET requests.
|
5
|
-
match ':controller(/:action(/:id(.:format)))', via: [:get, :post, :put, :delete]
|
2
|
+
resources :audits
|
6
3
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
ENV['RAILS_ENV'] = 'test'
|
2
2
|
|
3
|
-
|
3
|
+
if Bundler.definition.dependencies.map(&:name).include?('protected_attributes')
|
4
|
+
require 'protected_attributes'
|
5
|
+
end
|
4
6
|
require 'rails_app/config/environment'
|
5
7
|
require 'rspec/rails'
|
6
8
|
require 'audited'
|
7
9
|
require 'audited_spec_helpers'
|
10
|
+
require 'support/active_record/models'
|
11
|
+
load "audited/sweeper.rb" # force to reload sweeper
|
8
12
|
|
9
13
|
SPEC_ROOT = Pathname.new(File.expand_path('../', __FILE__))
|
10
14
|
|
@@ -12,12 +16,6 @@ Dir[SPEC_ROOT.join('support/*.rb')].each{|f| require f }
|
|
12
16
|
|
13
17
|
RSpec.configure do |config|
|
14
18
|
config.include AuditedSpecHelpers
|
15
|
-
|
16
|
-
config.
|
17
|
-
Audited.audit_class = Audited::Adapters::ActiveRecord::Audit
|
18
|
-
end
|
19
|
-
|
20
|
-
config.before(:each, :adapter => :mongo_mapper) do
|
21
|
-
Audited.audit_class = Audited::Adapters::MongoMapper::Audit
|
22
|
-
end
|
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=)
|
23
21
|
end
|
@@ -4,35 +4,40 @@ require File.expand_path('../schema', __FILE__)
|
|
4
4
|
module Models
|
5
5
|
module ActiveRecord
|
6
6
|
class User < ::ActiveRecord::Base
|
7
|
-
audited :
|
7
|
+
audited allow_mass_assignment: true, except: :password
|
8
8
|
|
9
|
-
attr_protected :logins
|
9
|
+
attr_protected :logins if respond_to?(:attr_protected)
|
10
10
|
|
11
11
|
def name=(val)
|
12
12
|
write_attribute(:name, CGI.escapeHTML(val))
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
class UserOnlyPassword < ::ActiveRecord::Base
|
17
|
+
self.table_name = :users
|
18
|
+
audited allow_mass_assignment: true, only: :password
|
19
|
+
end
|
20
|
+
|
16
21
|
class CommentRequiredUser < ::ActiveRecord::Base
|
17
22
|
self.table_name = :users
|
18
|
-
audited :
|
23
|
+
audited comment_required: true
|
19
24
|
end
|
20
25
|
|
21
26
|
class AccessibleAfterDeclarationUser < ::ActiveRecord::Base
|
22
27
|
self.table_name = :users
|
23
28
|
audited
|
24
|
-
attr_accessible :name, :username, :password
|
29
|
+
attr_accessible :name, :username, :password if respond_to?(:attr_accessible)
|
25
30
|
end
|
26
31
|
|
27
32
|
class AccessibleBeforeDeclarationUser < ::ActiveRecord::Base
|
28
33
|
self.table_name = :users
|
29
|
-
attr_accessible :name, :username, :password # declare attr_accessible before calling aaa
|
34
|
+
attr_accessible :name, :username, :password if respond_to?(:attr_accessible) # declare attr_accessible before calling aaa
|
30
35
|
audited
|
31
36
|
end
|
32
37
|
|
33
38
|
class NoAttributeProtectionUser < ::ActiveRecord::Base
|
34
39
|
self.table_name = :users
|
35
|
-
audited :
|
40
|
+
audited allow_mass_assignment: true
|
36
41
|
end
|
37
42
|
|
38
43
|
class UserWithAfterAudit < ::ActiveRecord::Base
|
@@ -40,6 +45,8 @@ module Models
|
|
40
45
|
audited
|
41
46
|
attr_accessor :bogus_attr, :around_attr
|
42
47
|
|
48
|
+
private
|
49
|
+
|
43
50
|
def after_audit
|
44
51
|
self.bogus_attr = "do something"
|
45
52
|
end
|
@@ -64,29 +71,29 @@ module Models
|
|
64
71
|
|
65
72
|
class OwnedCompany < ::ActiveRecord::Base
|
66
73
|
self.table_name = 'companies'
|
67
|
-
belongs_to :owner, :
|
68
|
-
attr_accessible :name, :owner # declare attr_accessible before calling aaa
|
69
|
-
audited :
|
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
|
70
77
|
end
|
71
78
|
|
72
79
|
class OnUpdateDestroy < ::ActiveRecord::Base
|
73
80
|
self.table_name = 'companies'
|
74
|
-
audited :
|
81
|
+
audited on: [:update, :destroy]
|
75
82
|
end
|
76
83
|
|
77
84
|
class OnCreateDestroy < ::ActiveRecord::Base
|
78
85
|
self.table_name = 'companies'
|
79
|
-
audited :
|
86
|
+
audited on: [:create, :destroy]
|
80
87
|
end
|
81
88
|
|
82
89
|
class OnCreateDestroyExceptName < ::ActiveRecord::Base
|
83
90
|
self.table_name = 'companies'
|
84
|
-
audited :
|
91
|
+
audited except: :name, on: [:create, :destroy]
|
85
92
|
end
|
86
93
|
|
87
94
|
class OnCreateUpdate < ::ActiveRecord::Base
|
88
95
|
self.table_name = 'companies'
|
89
|
-
audited :
|
96
|
+
audited on: [:create, :update]
|
90
97
|
end
|
91
98
|
end
|
92
99
|
end
|
@@ -1,38 +1,62 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
require 'logger'
|
3
3
|
|
4
|
-
|
5
|
-
ActiveRecord::Base.
|
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
|
+
|
6
29
|
ActiveRecord::Migration.verbose = false
|
30
|
+
ActiveRecord::Base.establish_connection
|
7
31
|
|
8
32
|
ActiveRecord::Schema.define do
|
9
|
-
create_table :users
|
33
|
+
create_table :users do |t|
|
10
34
|
t.column :name, :string
|
11
35
|
t.column :username, :string
|
12
36
|
t.column :password, :string
|
13
37
|
t.column :activated, :boolean
|
14
38
|
t.column :suspended_at, :datetime
|
15
|
-
t.column :logins, :integer, :
|
39
|
+
t.column :logins, :integer, default: 0
|
16
40
|
t.column :created_at, :datetime
|
17
41
|
t.column :updated_at, :datetime
|
18
42
|
end
|
19
43
|
|
20
|
-
create_table :companies
|
44
|
+
create_table :companies do |t|
|
21
45
|
t.column :name, :string
|
22
46
|
t.column :owner_id, :integer
|
23
47
|
t.column :type, :string
|
24
48
|
end
|
25
49
|
|
26
|
-
create_table :authors
|
50
|
+
create_table :authors do |t|
|
27
51
|
t.column :name, :string
|
28
52
|
end
|
29
53
|
|
30
|
-
create_table :books
|
54
|
+
create_table :books do |t|
|
31
55
|
t.column :authord_id, :integer
|
32
56
|
t.column :title, :string
|
33
57
|
end
|
34
58
|
|
35
|
-
create_table :audits
|
59
|
+
create_table :audits do |t|
|
36
60
|
t.column :auditable_id, :integer
|
37
61
|
t.column :auditable_type, :string
|
38
62
|
t.column :associated_id, :integer
|
@@ -42,16 +66,16 @@ ActiveRecord::Schema.define do
|
|
42
66
|
t.column :username, :string
|
43
67
|
t.column :action, :string
|
44
68
|
t.column :audited_changes, :text
|
45
|
-
t.column :version, :integer, :
|
69
|
+
t.column :version, :integer, default: 0
|
46
70
|
t.column :comment, :string
|
47
71
|
t.column :remote_address, :string
|
48
72
|
t.column :request_uuid, :string
|
49
73
|
t.column :created_at, :datetime
|
50
74
|
end
|
51
75
|
|
52
|
-
add_index :audits, [:auditable_id, :auditable_type], :
|
53
|
-
add_index :audits, [:associated_id, :associated_type], :
|
54
|
-
add_index :audits, [:user_id, :user_type], :
|
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'
|
55
79
|
add_index :audits, :request_uuid
|
56
80
|
add_index :audits, :created_at
|
57
81
|
end
|
data/test/db/version_1.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
ActiveRecord::Schema.define do
|
2
|
-
create_table :audits, :
|
2
|
+
create_table :audits, force: true do |t|
|
3
3
|
t.column :auditable_id, :integer
|
4
4
|
t.column :auditable_type, :string
|
5
5
|
t.column :user_id, :integer
|
@@ -7,11 +7,11 @@ ActiveRecord::Schema.define do
|
|
7
7
|
t.column :username, :string
|
8
8
|
t.column :action, :string
|
9
9
|
t.column :changes, :text
|
10
|
-
t.column :version, :integer, :
|
10
|
+
t.column :version, :integer, default: 0
|
11
11
|
t.column :created_at, :datetime
|
12
12
|
end
|
13
13
|
|
14
|
-
add_index :audits, [:auditable_id, :auditable_type], :
|
15
|
-
add_index :audits, [:user_id, :user_type], :
|
14
|
+
add_index :audits, [:auditable_id, :auditable_type], name: 'auditable_index'
|
15
|
+
add_index :audits, [:user_id, :user_type], name: 'user_index'
|
16
16
|
add_index :audits, :created_at
|
17
17
|
end
|
data/test/db/version_2.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
ActiveRecord::Schema.define do
|
2
|
-
create_table :audits, :
|
2
|
+
create_table :audits, force: true do |t|
|
3
3
|
t.column :auditable_id, :integer
|
4
4
|
t.column :auditable_type, :string
|
5
5
|
t.column :user_id, :integer
|
@@ -7,12 +7,12 @@ ActiveRecord::Schema.define do
|
|
7
7
|
t.column :username, :string
|
8
8
|
t.column :action, :string
|
9
9
|
t.column :changes, :text
|
10
|
-
t.column :version, :integer, :
|
10
|
+
t.column :version, :integer, default: 0
|
11
11
|
t.column :comment, :string
|
12
12
|
t.column :created_at, :datetime
|
13
13
|
end
|
14
14
|
|
15
|
-
add_index :audits, [:auditable_id, :auditable_type], :
|
16
|
-
add_index :audits, [:user_id, :user_type], :
|
15
|
+
add_index :audits, [:auditable_id, :auditable_type], name: 'auditable_index'
|
16
|
+
add_index :audits, [:user_id, :user_type], name: 'user_index'
|
17
17
|
add_index :audits, :created_at
|
18
18
|
end
|
data/test/db/version_3.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
ActiveRecord::Schema.define do
|
2
|
-
create_table :audits, :
|
2
|
+
create_table :audits, force: true do |t|
|
3
3
|
t.column :auditable_id, :integer
|
4
4
|
t.column :auditable_type, :string
|
5
5
|
t.column :user_id, :integer
|
@@ -7,13 +7,13 @@ ActiveRecord::Schema.define do
|
|
7
7
|
t.column :username, :string
|
8
8
|
t.column :action, :string
|
9
9
|
t.column :audited_changes, :text
|
10
|
-
t.column :version, :integer, :
|
10
|
+
t.column :version, :integer, default: 0
|
11
11
|
t.column :comment, :string
|
12
12
|
t.column :created_at, :datetime
|
13
13
|
end
|
14
14
|
|
15
|
-
add_index :audits, [:auditable_id, :auditable_type], :
|
16
|
-
add_index :audits, [:user_id, :user_type], :
|
15
|
+
add_index :audits, [:auditable_id, :auditable_type], name: 'auditable_index'
|
16
|
+
add_index :audits, [:user_id, :user_type], name: 'user_index'
|
17
17
|
add_index :audits, :created_at
|
18
18
|
end
|
19
19
|
|