database_consistency 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8a45e3403f929db1a3524719b0f955b06ac32c922136f5ee930d2eb2b70bdd0
4
- data.tar.gz: cc864d1567c17eb3e546321c2d4a1448e2bfc02aec6b4ae25dc7a4f5e6eb5f50
3
+ metadata.gz: dd7ba14920b79a253aa4c1b603f4dde0478780f0a0a0b4342eb6a928b153545e
4
+ data.tar.gz: f655cf5cff2f43b0bef8986fa9617c7891b484f375e34289aaa585b3541f21cb
5
5
  SHA512:
6
- metadata.gz: 25ef86b694af8d420c054b6e1a900803d1c577a5091470d274ca54c9880786a620379ccbdcab408c2f697d94878a53e94bd175e395e77d040c6c245105b2a141
7
- data.tar.gz: 4cd6ea61d0a4243260b754677d1268d5fb4b207f3d0428c4af2db5d485b6dc8202cd9725aaa96696cd36497e0aaea130ea4a3c8a3fa06675f14b74be678bde84
6
+ metadata.gz: 3f52bb80a9d738cd62d4385027069b46ea1fd6c8f99fc8aeb161d0d5e75dff8e6004fe61abc0f76497d7dee9e7247ba0cd066018d1920ee23063b928363c25a4
7
+ data.tar.gz: 796243796d3e50f1aaa5dd750523be44c1db2c8736cf97720921435026b60283be024253e9972a7f2cedc2ed63ba0bdde3e991dcefb1bb88fe91c9a85a20c282
@@ -16,11 +16,13 @@ module DatabaseConsistency
16
16
  # - association isn't a `HasOne` or `HasMany`
17
17
  # - association has `through` option
18
18
  # - associated class doesn't exist
19
+ # - associated class's table doesn't exist
19
20
  def preconditions
20
21
  %i[
21
22
  has_one
22
23
  has_many
23
- ].include?(association.macro) && association.through_reflection.nil? && association.klass
24
+ ].include?(association.macro) && association.through_reflection.nil? &&
25
+ association.klass.table_exists?
24
26
  rescue StandardError
25
27
  false
26
28
  end
@@ -39,7 +41,7 @@ module DatabaseConsistency
39
41
  end
40
42
 
41
43
  def check_unique_has_one
42
- if unique_index
44
+ if unique_index || primary_key_columns.sort == association_keys
43
45
  report_template(:ok)
44
46
  else
45
47
  report_template(:fail, error_slug: :has_one_missing_unique_index)
@@ -47,7 +49,7 @@ module DatabaseConsistency
47
49
  end
48
50
 
49
51
  def check_remaining
50
- if index
52
+ if index || primary_key_columns.first(association_keys.size).sort == association_keys
51
53
  report_template(:ok)
52
54
  else
53
55
  report_template(:fail, error_slug: :association_missing_index)
@@ -85,6 +87,13 @@ module DatabaseConsistency
85
87
  end
86
88
  end
87
89
 
90
+ # The primary key is an implicit unique index, so it covers the association as well.
91
+ def primary_key_columns
92
+ @primary_key_columns ||= Array(
93
+ association.klass.connection_pool.with_connection { |conn| conn.primary_key(association.klass.table_name) }
94
+ ).map(&:to_s)
95
+ end
96
+
88
97
  def association_keys
89
98
  @association_keys ||= [association.foreign_key, association.type].compact.map(&:to_s).sort
90
99
  end
@@ -66,7 +66,11 @@ module DatabaseConsistency
66
66
  def project_klass?(klass)
67
67
  return true unless Module.respond_to?(:const_source_location) && defined?(Bundler)
68
68
 
69
- !Module.const_source_location(klass.to_s).first.to_s.include?(Bundler.bundle_path.to_s)
69
+ source_path = Module.const_source_location(klass.to_s).first.to_s
70
+ bundle_path = Bundler.bundle_path
71
+ bundle_paths = [bundle_path]
72
+ bundle_paths << bundle_path.realpath if bundle_path.exist?
73
+ bundle_paths.none? { |path| source_path.include?(path.to_s) }
70
74
  rescue NameError
71
75
  false
72
76
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DatabaseConsistency
4
- VERSION = '3.1.0'
4
+ VERSION = '3.1.1'
5
5
  end
@@ -7,15 +7,22 @@ module DatabaseConsistency
7
7
  private
8
8
 
9
9
  def template
10
- 'should have a foreign key with on_delete: :%<cascade_option>s in the database'
10
+ 'should have a foreign key %<cascade_option>s in the database'
11
11
  end
12
12
 
13
13
  def attributes
14
14
  {
15
- cascade_option: report.cascade_option
15
+ cascade_option: cascade_option_text
16
16
  }
17
17
  end
18
18
 
19
+ # nil stands for a foreign key without an on_delete option
20
+ def cascade_option_text
21
+ options = report.cascade_option.compact.map { |option| "with on_delete: :#{option}" }
22
+ options << 'without on_delete' if report.cascade_option.include?(nil)
23
+ options.join(' or ')
24
+ end
25
+
19
26
  def unique_attributes
20
27
  {
21
28
  foreign_table: report.foreign_table,
@@ -31,7 +31,7 @@ module DatabaseConsistency
31
31
  klass =
32
32
  if report.error_slug
33
33
  begin
34
- "DatabaseConsistency::Writers::Simple::#{report.error_slug.to_s.classify}".constantize
34
+ "DatabaseConsistency::Writers::Simple::#{report.error_slug.to_s.camelize}".constantize
35
35
  rescue NameError
36
36
  Simple::DefaultMessage
37
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: database_consistency
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgeniy Demin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-20 00:00:00.000000000 Z
11
+ date: 2026-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord