Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add table_without_primary_key checker #173

Merged
merged 1 commit into from
Mar 1, 2024
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 @@ -15,6 +15,7 @@ can detect:
* incorrect values of `dependent` on associations - [`active_record_doctor:incorrect_dependent_option`](#detecting-incorrect-dependent-option-on-associations)
* 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)

It can also:

Expand Down Expand Up @@ -602,6 +603,29 @@ Supported configuration options:
- `ignore_columns` - foreign keys, written as table.column, that should not be
checked.

### Detecting Tables Without Primary Keys

Tables should have primary keys. Otherwise, it becomes problematic to easily find a specific record,
logical replication in PostgreSQL will be troublesome, because all the rows need to be unique
in the table then etc.

Running the command below will list all tables without primary keys:

```
bundle exec rake active_record_doctor:table_without_primary_key
```

The output of the command looks like this:

```
add a primary key to companies
```

Supported configuration options:

- `enabled` - set to `false` to disable the detector altogether
- `ignore_tables` - tables whose primary key existense 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 @@ -20,6 +20,7 @@
require "active_record_doctor/detectors/incorrect_dependent_option"
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/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 @@ -58,6 +58,10 @@
enabled: true,
ignore_tables: []

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

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

require "active_record_doctor/detectors/base"

module ActiveRecordDoctor
module Detectors
class TableWithoutPrimaryKey < Base # :nodoc:
@description = "detect tables without primary keys"
@config = {
ignore_tables: {
description: "tables whose primary key existense should not be checked",
global: true
}
}

private

def message(table:)
"add a primary key to #{table}"
end

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

class ActiveRecordDoctor::Detectors::TableWithoutPrimaryKeyTest < Minitest::Test
def test_table_without_primary_key_reported
Context.create_table(:companies, id: false) do |t|
t.string :name
end

assert_problems(<<~OUTPUT)
add a primary key to companies
OUTPUT
end

def test_table_with_primary_key_is_not_reported
Context.create_table(:companies)
refute_problems
end

def test_config_ignore_tables
Context.create_table(:companies, id: false) do |t|
t.string :name
end

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

refute_problems
end

def test_global_ignore_tables
Context.create_table(:companies, id: false) do |t|
t.string :name
end

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

refute_problems
end
end
Loading