Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ can detect:
* primary keys having short integer types - [`active_record_doctor:short_primary_key_type`](#detecting-primary-keys-having-short-integer-types)
* mismatched foreign key types - [`active_record_doctor:mismatched_foreign_key_type`](#detecting-mismatched-foreign-key-types)
* tables without primary keys - [`active_record_doctor:table_without_primary_key`](#detecting-tables-without-primary-keys)
* tables without timestamps - [`active_record_doctor:table_without_timestamps`](#detecting-tables-without-timestamps)

It can also:

Expand Down Expand Up @@ -642,6 +643,29 @@ Supported configuration options:
- `enabled` - set to `false` to disable the detector altogether
- `ignore_tables` - tables whose primary key existence should not be checked

### Detecting Tables Without Timestamps

Tables should have timestamp columns (`created_at`/`updated_at`). Otherwise, it becomes problematic
to easily find when the record was created/updated, if the table is active or can be removed,
automatic Rails cache expiration after record updates is not possible.

Running the command below will list all tables without default timestamp columns:

```
bundle exec rake active_record_doctor:table_without_timestamps
```

The output of the command looks like this:

```
add a created_at column to companies
```

Supported configuration options:

- `enabled` - set to `false` to disable the detector altogether
- `ignore_tables` - tables whose timestamp columns existence should not be checked

## Ruby and Rails Compatibility Policy

The goal of the policy is to ensure proper functioning in reasonable
Expand Down
1 change: 1 addition & 0 deletions lib/active_record_doctor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
require "active_record_doctor/detectors/short_primary_key_type"
require "active_record_doctor/detectors/mismatched_foreign_key_type"
require "active_record_doctor/detectors/table_without_primary_key"
require "active_record_doctor/detectors/table_without_timestamps"
require "active_record_doctor/errors"
require "active_record_doctor/help"
require "active_record_doctor/runner"
Expand Down
4 changes: 4 additions & 0 deletions lib/active_record_doctor/config/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@
enabled: true,
ignore_tables: []

detector :table_without_timestamps,
enabled: true,
ignore_tables: []

detector :undefined_table_references,
enabled: true,
ignore_models: []
Expand Down
38 changes: 38 additions & 0 deletions lib/active_record_doctor/detectors/table_without_timestamps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require "active_record_doctor/detectors/base"

module ActiveRecordDoctor
module Detectors
class TableWithoutTimestamps < Base # :nodoc:
@description = "detect tables without created_at/updated_at columns"
@config = {
ignore_tables: {
description: "tables whose timestamp columns existence should not be checked",
global: true
}
}

private

TIMESTAMPS = {
"created_at" => "created_on",
"updated_at" => "updated_on"
}.freeze

def message(table:, column:)
"add a #{column} column to #{table}"
end

def detect
each_table(except: config(:ignore_tables)) do |table|
TIMESTAMPS.each do |column, alternative_column|
unless column(table, column) || column(table, alternative_column)
problem!(table: table, column: column)
end
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

class ActiveRecordDoctor::Detectors::TableWithoutTimestampsTest < Minitest::Test
def test_table_without_timestamps_reported
Context.create_table(:companies) do |t|
t.string :name
end

assert_problems(<<~OUTPUT)
add a created_at column to companies
add a updated_at column to companies
OUTPUT
end

def test_table_with_timestamps_is_not_reported
Context.create_table(:companies) do |t|
t.timestamps
end
refute_problems
end

def test_table_with_alternative_timestamps_is_not_reported
Context.create_table(:companies) do |t|
t.timestamp :created_on
t.timestamp :updated_on
end
refute_problems
end

def test_config_ignore_tables
Context.create_table(:companies)

config_file(<<-CONFIG)
ActiveRecordDoctor.configure do |config|
config.detector :table_without_timestamps,
ignore_tables: ["companies"]
end
CONFIG

refute_problems
end

def test_global_ignore_tables
Context.create_table(:companies)

config_file(<<-CONFIG)
ActiveRecordDoctor.configure do |config|
config.global :ignore_tables, ["companies"]
end
CONFIG

refute_problems
end
end