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 Jan 31, 2023
1 parent 7fcc902 commit d6f61d6
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 9 deletions.
17 changes: 17 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,17 @@
# frozen_string_literal: true

class <%= migration_class_name %> < <%= migration_parent %>
def self.up
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, :action, true
change_column_null :audits, :audited_changes, true
change_column_null :audits, :version, true
change_column_null :audits, :created_at, true
end
end
8 changes: 4 additions & 4 deletions lib/generators/audited/templates/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ def self.up
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
12 changes: 11 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.map { |column| [column.name, column] }.to_h
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,16 @@ 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 = [
"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
8 changes: 4 additions & 4 deletions spec/support/active_record/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@
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
13 changes: 13 additions & 0 deletions test/upgrade_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,17 @@ class UpgradeGeneratorTest < Rails::Generators::TestCase
assert_includes(content, "class AddCommentToAudits < ActiveRecord::Migration[#{ActiveRecord::Migration.current_version}]\n")
end
end

test "should set several audits columns NOT NULL" do
load_schema 1

run_generator %w[upgrade]

assert_migration "db/migrate/change_audits_columns_not_null.rb" do |content|
assert_includes(content, 'change_column_null :audits, :action, false')
assert_includes(content, 'change_column_null :audits, :audited_changes, false')
assert_includes(content, 'change_column_null :audits, :version, false')
assert_includes(content, 'change_column_null :audits, :created_at, false')
end
end
end

0 comments on commit d6f61d6

Please sign in to comment.