Skip to content

Commit

Permalink
Make several columns in the audits table NOT NULL
Browse files Browse the repository at this point in the history
Improve data integrity by adding NOT NULL constraints to columns that
should _always_ have a value. This helps catch application and library
bugs earlier by catching mishandling of data.

Fixes collectiveidea#572
  • Loading branch information
jdufresne committed Apr 4, 2022
1 parent 39d29e2 commit 3d7f5d3
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 15 deletions.
21 changes: 21 additions & 0 deletions lib/generators/audited/templates/change_audits_columns_not_null.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

class <%= migration_class_name %> < <%= migration_parent %>
def self.up
change_column_null :audits, :auditable_id, false
change_column_null :audits, :auditable_type, false
change_column_null :audits, :action, false
change_column_null :audits, :audited_changes, false
change_column_null :audits, :version, false
change_column_null :audits, :created_at, false
end

def self.down
change_column_null :audits, :auditable_id, true
change_column_null :audits, :auditable_type, true
change_column_null :audits, :action, true
change_column_null :audits, :audited_changes, true
change_column_null :audits, :version, true
change_column_null :audits, :created_at, true
end
end
12 changes: 6 additions & 6 deletions lib/generators/audited/templates/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
class <%= migration_class_name %> < <%= migration_parent %>
def self.up
create_table :audits, :force => true do |t|
t.column :auditable_id, :integer
t.column :auditable_type, :string
t.column :auditable_id, :integer, null: false
t.column :auditable_type, :string, null: false
t.column :associated_id, :integer
t.column :associated_type, :string
t.column :user_id, :<%= options[:audited_user_id_column_type] %>
t.column :user_type, :string
t.column :username, :string
t.column :action, :string
t.column :audited_changes, :<%= options[:audited_changes_column_type] %>
t.column :version, :integer, :default => 0
t.column :action, :string, null: false
t.column :audited_changes, :<%= options[:audited_changes_column_type] %>, null: false
t.column :version, :integer, :default => 0, null: false
t.column :comment, :string
t.column :remote_address, :string
t.column :request_uuid, :string
t.column :created_at, :datetime
t.column :created_at, :datetime, null: false
end

add_index :audits, [:auditable_type, :auditable_id, :version], :name => 'auditable_index'
Expand Down
14 changes: 13 additions & 1 deletion lib/generators/audited/upgrade_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def copy_templates

def migrations_to_be_applied
Audited::Audit.reset_column_information
columns = Audited::Audit.columns.map(&:name)
columns = Audited::Audit.columns.to_h { |column| [column.name, column] }
indexes = Audited::Audit.connection.indexes(Audited::Audit.table_name)

yield :add_comment_to_audits unless columns.include?("comment")
Expand Down Expand Up @@ -64,6 +64,18 @@ def migrations_to_be_applied
if indexes.any? { |i| i.columns == %w[auditable_type auditable_id] }
yield :add_version_to_auditable_index
end

columns_not_null = [
"auditable_id",
"auditable_type",
"action",
"audited_changes",
"version",
"created_at",
]
if columns_not_null.any? { |column| columns[column].null }
yield :change_audits_columns_not_null
end
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/audited/auditor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ def non_column_attr=(val)
end

it "should be able to reconstruct a destroyed record without history" do
@user.audits.delete_all
Audited::Audit.where(auditable: @user).delete_all
@user.destroy

revision = @user.audits.first.revision
Expand Down Expand Up @@ -626,7 +626,7 @@ def stub_global_max_audits(max_audits)
end

it "should be empty if no audits exist" do
user.audits.delete_all
Audited::Audit.where(auditable: user).delete_all
expect(user.revisions).to be_empty
end

Expand Down
12 changes: 6 additions & 6 deletions spec/support/active_record/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,20 @@
end

create_table :audits do |t|
t.column :auditable_id, :integer
t.column :auditable_type, :string
t.column :auditable_id, :integer, null: false
t.column :auditable_type, :string, null: false
t.column :associated_id, :integer
t.column :associated_type, :string
t.column :user_id, :integer
t.column :user_type, :string
t.column :username, :string
t.column :action, :string
t.column :audited_changes, :text
t.column :version, :integer, default: 0
t.column :action, :string, null: false
t.column :audited_changes, :text, null: false
t.column :version, :integer, default: 0, null: false
t.column :comment, :string
t.column :remote_address, :string
t.column :request_uuid, :string
t.column :created_at, :datetime
t.column :created_at, :datetime, null: false
end

add_index :audits, [:auditable_id, :auditable_type], name: "auditable_index"
Expand Down

0 comments on commit 3d7f5d3

Please sign in to comment.