foreign_key_checker 0.3.0 → 0.4.0
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 +4 -4
- data/README.md +1 -1
- data/lib/foreign_key_checker.rb +16 -3
- data/lib/foreign_key_checker/checkers/relations.rb +122 -0
- data/lib/foreign_key_checker/checkers/tables.rb +88 -0
- data/lib/foreign_key_checker/utils.rb +66 -1
- data/lib/foreign_key_checker/version.rb +1 -1
- metadata +106 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf9685280dd2c9ad8232c3b4fe7d4f72dcc56ccdbbaf0b55d826792196185f05
|
4
|
+
data.tar.gz: de9a1d21793299c0df12e92b09fd2661b160d9794d6bb01a7080478fecc3db96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f3b6138b99b780ed15ab03c43c0745bfc9511089e4fe0b4bb29cc962d232f7d942d3e314dc56bc8422e193631872d7415a5a28251281fad1bca704fb3c2ab6b
|
7
|
+
data.tar.gz: d7c3c677d063a6e2210d3627caac91431024e940b44e4e2b33c912f48c532a662c81678a1f5aa32f8cccffe19c3bdf0fbd7e10c13796f129de2dc9c60044705d
|
data/README.md
CHANGED
@@ -23,7 +23,7 @@ ForeignKeyChecker.check.each do |key, result|
|
|
23
23
|
end
|
24
24
|
```
|
25
25
|
|
26
|
-
Get general information about foreign keys
|
26
|
+
Get general information about foreign keys
|
27
27
|
```ruby
|
28
28
|
ForeignKeyChecker::Utils.get_foreign_keys_hash
|
29
29
|
# => {"users"=>[#<ForeignKeyChecker::Utils::Result:0x00005645e51756e8 @from_table="user_rating_changes", @from_column="user_id", @to_table="users", @to_column="id">]}
|
data/lib/foreign_key_checker.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
require "foreign_key_checker/railtie"
|
2
2
|
require 'foreign_key_checker/utils'
|
3
|
+
module ForeignKeyChecker::Checkers
|
4
|
+
end
|
5
|
+
require 'foreign_key_checker/checkers/relations'
|
6
|
+
require 'foreign_key_checker/checkers/tables'
|
3
7
|
|
4
8
|
module ForeignKeyChecker
|
5
9
|
class TypeMismatch < StandardError; end
|
@@ -162,12 +166,21 @@ module ForeignKeyChecker
|
|
162
166
|
def check_types(model, association)
|
163
167
|
type_from = model.columns_hash[association.foreign_key.to_s].sql_type
|
164
168
|
type_to = association.klass.columns_hash[association.klass.primary_key.to_s].sql_type
|
165
|
-
raise TypeMismatch, "TypeMissMatch #{type_from} != #{type_to}" if type_from != type_to
|
169
|
+
raise TypeMismatch, "TypeMissMatch for relation #{model}##{association.name} #{type_from} != #{type_to}" if type_from != type_to
|
166
170
|
end
|
167
171
|
|
168
172
|
def check_foreign_key_bt_association(model, association)
|
169
173
|
return if model.name.starts_with?('HABTM_')
|
170
|
-
|
174
|
+
begin
|
175
|
+
related = association.klass
|
176
|
+
rescue NameError => error
|
177
|
+
@result[:broken] << BrokenRelationResult.new(
|
178
|
+
model: model,
|
179
|
+
association: association,
|
180
|
+
error: error,
|
181
|
+
)
|
182
|
+
return
|
183
|
+
end
|
171
184
|
|
172
185
|
column_name = model.connection.quote_column_name(association.foreign_key)
|
173
186
|
scope = model.left_outer_joins(association.name).where(
|
@@ -188,7 +201,7 @@ module ForeignKeyChecker
|
|
188
201
|
end
|
189
202
|
end
|
190
203
|
|
191
|
-
if foreign_keys && !model.connection.foreign_key_exists?(model.table_name, related.table_name)
|
204
|
+
if foreign_keys && !model.connection.foreign_key_exists?(model.table_name, related.table_name, column: association.foreign_key, primary_key: related.primary_key)
|
192
205
|
scope.first
|
193
206
|
@result[:foreign_keys] << ForeignKeyResult.new(
|
194
207
|
model: model,
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'foreign_key_checker/utils'
|
2
|
+
|
3
|
+
module ForeignKeyChecker::Checkers::Relations
|
4
|
+
class Result
|
5
|
+
attr_reader :ok, :model, :association, :fk, :error, :table
|
6
|
+
def initialize(**args)
|
7
|
+
%i[model association ok error fk table].each do |key|
|
8
|
+
instance_variable_set("@#{key}", args[key])
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
class JoinResult < Result
|
13
|
+
def message
|
14
|
+
"expect { #{model.to_s}.joins(:#{association.name}).first }.to_not raise_exception" if !ok
|
15
|
+
end
|
16
|
+
end
|
17
|
+
class ErrorResult < Result
|
18
|
+
def message
|
19
|
+
"`#{model.to_s}##{association.name}` is broken\n#{error.class.to_s}\n#{error.message}\n#{error.backtrace.join("\n")}" if !ok
|
20
|
+
end
|
21
|
+
end
|
22
|
+
class HasOneOrManyResult < Result
|
23
|
+
def message
|
24
|
+
"expected has_many or has_one association for #{fk.inspect}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
class HasOneOrManyDependentResult < Result
|
28
|
+
def message
|
29
|
+
"expected has_many or has_one association with dependent option for #{fk.inspect}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
class NoModelResult < Result
|
33
|
+
def message
|
34
|
+
"expected find model for table #{table}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
def self.check_by_join
|
38
|
+
Rails.application.eager_load!
|
39
|
+
models = ActiveRecord::Base.descendants
|
40
|
+
models.each_with_object([]) do |model, results|
|
41
|
+
next if model.to_s.include?('HABTM')
|
42
|
+
model.reflect_on_all_associations.each do |association|
|
43
|
+
begin
|
44
|
+
next if association.options[:polymorphic]
|
45
|
+
next if association.scope && association.scope.is_a?(Proc) && association.scope.arity > 0
|
46
|
+
next if model.connection_specification_name != association.klass.connection_specification_name
|
47
|
+
|
48
|
+
model.joins(association.name).first
|
49
|
+
result = JoinResult.new(model: model, association: association, ok: true)
|
50
|
+
yield result if block_given?
|
51
|
+
results << result
|
52
|
+
rescue => e
|
53
|
+
result = JoinResult.new(model: model, association: association, ok: false, error: e)
|
54
|
+
yield result if block_given?
|
55
|
+
results << result
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.check_by_fks
|
62
|
+
Rails.application.eager_load!
|
63
|
+
models = ActiveRecord::Base.descendants.group_by(&:table_name)
|
64
|
+
check_relation = proc do |model, fk, association|
|
65
|
+
begin
|
66
|
+
pk = association.options[:primary_key] || model.primary_key
|
67
|
+
association.klass.table_name.to_s == fk.from_table.to_s && association.foreign_key.to_s == fk.from_column.to_s && pk.to_s == fk.to_column.to_s
|
68
|
+
rescue => e
|
69
|
+
if block_given?
|
70
|
+
yield ErrorResult.new(model: model, association: association, fk: fk, ok: false, error: e)
|
71
|
+
else
|
72
|
+
p model
|
73
|
+
p fk
|
74
|
+
p association
|
75
|
+
raise e
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
ForeignKeyChecker::Utils.get_foreign_keys_hash.each do |to_table, fks|
|
80
|
+
fks.each do |fk|
|
81
|
+
unless models.key?(fk.to_table)
|
82
|
+
result = NoModelResult.new(ok: false, table: fk.to_table)
|
83
|
+
if block_given?
|
84
|
+
yield result
|
85
|
+
else
|
86
|
+
raise result.message
|
87
|
+
end
|
88
|
+
next
|
89
|
+
end
|
90
|
+
models[fk.to_table].each do |model|
|
91
|
+
next if model.connection_specification_name != 'primary'
|
92
|
+
ok = false
|
93
|
+
ok ||= !!model.reflect_on_all_associations(:has_many).find do |association|
|
94
|
+
check_relation.call(model, fk, association)
|
95
|
+
end
|
96
|
+
ok ||= !!model.reflect_on_all_associations(:has_one).find do |association|
|
97
|
+
check_relation.call(model, fk, association)
|
98
|
+
end
|
99
|
+
if block_given?
|
100
|
+
yield HasOneOrManyResult.new(model: model, fk: fk, ok: ok)
|
101
|
+
else
|
102
|
+
raise "expected has_many or has_one association for #{fk.inspect}" if !ok
|
103
|
+
end
|
104
|
+
next if !ok
|
105
|
+
|
106
|
+
dep = false
|
107
|
+
dep ||= !!model.reflect_on_all_associations(:has_many).find do |association|
|
108
|
+
check_relation.call(model, fk, association) && association.options[:dependent]
|
109
|
+
end
|
110
|
+
dep ||= !!model.reflect_on_all_associations(:has_one).find do |association|
|
111
|
+
check_relation.call(model, fk, association) && association.options[:dependent]
|
112
|
+
end
|
113
|
+
if block_given?
|
114
|
+
yield HasOneOrManyDependentResult.new(model: model, fk: fk, ok: ok)
|
115
|
+
else
|
116
|
+
raise "expected has_many or has_one association with dependent option for #{fk.inspect}" if !dep
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'foreign_key_checker/utils'
|
2
|
+
|
3
|
+
# Стоит использовать в тех случаях, когда подключается rails к уже существующей базе
|
4
|
+
# Можно проверить, для каких таблиц всё ещё нет ActiveRecord-моделей
|
5
|
+
module ForeignKeyChecker::Checkers::Tables
|
6
|
+
SPECIAL_TABLES = ['schema_migrations', 'ar_internal_metadata'].freeze
|
7
|
+
# Список таблиц, не описанных моделями (в том числе HABTM-моделями, сгенерированными автоматически rails)
|
8
|
+
def self.without_models(specification_name = 'primary')
|
9
|
+
Rails.application.eager_load!
|
10
|
+
|
11
|
+
actual_tables = ForeignKeyChecker::Utils.get_tables
|
12
|
+
actual_tables - modelised_tables(specification_name) - SPECIAL_TABLES
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.without_foreign_keys(specification_name = 'primary')
|
16
|
+
all_fks = ForeignKeyChecker::Utils.get_foreign_keys
|
17
|
+
results = []
|
18
|
+
models(specification_name).each do |model|
|
19
|
+
model.column_names.each do |column_name|
|
20
|
+
next unless column_name.ends_with?('_id')
|
21
|
+
next if all_fks.find { |fk| fk.from_table = model.table_name && fk.from_column == column_name }
|
22
|
+
|
23
|
+
table_name = column_name.delete_suffix('_id')
|
24
|
+
results << ["#{table_name}.#{column_name}"]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.modelised_tables(specification_name = 'primary')
|
30
|
+
models(specification_name).map(&:table_name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.models(specification_name = 'primary')
|
34
|
+
ActiveRecord::Base.descendants.select do |model|
|
35
|
+
model.connection_specification_name == specification_name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def self.common_tables
|
41
|
+
ForeignKeyChecker::Utils.get_tables - SPECIAL_TABLES
|
42
|
+
end
|
43
|
+
|
44
|
+
class Result
|
45
|
+
attr_reader :table_name, :foreign_keys, :internal_references
|
46
|
+
def initialize(**args)
|
47
|
+
%i[table_name foreign_keys internal_references].each do |key|
|
48
|
+
instance_variable_set("@#{key}", args[key] || args[key].to_s)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def ok?
|
53
|
+
foreign_keys.blank?
|
54
|
+
end
|
55
|
+
|
56
|
+
def referenced?
|
57
|
+
foreign_keys.present?
|
58
|
+
end
|
59
|
+
|
60
|
+
def ext_ref?
|
61
|
+
!internal_references
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.check
|
67
|
+
tables = without_models
|
68
|
+
fks = ForeignKeyChecker::Utils.get_foreign_keys_hash
|
69
|
+
fks.default = []
|
70
|
+
tables.map do |table|
|
71
|
+
Result.new(
|
72
|
+
table_name: table,
|
73
|
+
foreign_keys: fks[table] || [],
|
74
|
+
internal_references: (fks[table].map(&:from_table) - tables).empty?,
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# TODO вспомнить, что я тут задумал
|
80
|
+
def self.ordered(results = check)
|
81
|
+
return results if results.size == 0
|
82
|
+
oks = results.select(&:ok?)
|
83
|
+
if oks.size == 0
|
84
|
+
raise "no ok"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -9,7 +9,7 @@ module ForeignKeyChecker
|
|
9
9
|
class UnsupportedConnectionAdapter < StandardError; end
|
10
10
|
def self.get_foreign_keys(model = ActiveRecord::Base)
|
11
11
|
adapter = model.connection_config[:adapter]
|
12
|
-
raise(UnsupportedConnectionAdapter, adapter) unless %w[postgresql mysql2].include?(adapter)
|
12
|
+
raise(UnsupportedConnectionAdapter, adapter) unless %w[postgresql mysql2 sqlserver sqlite3].include?(adapter)
|
13
13
|
|
14
14
|
connection = model.connection
|
15
15
|
send("get_#{adapter}_foreign_keys", connection)
|
@@ -22,6 +22,22 @@ module ForeignKeyChecker
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def self.get_sqlite3_foreign_keys(connection)
|
26
|
+
res = connection.select_all <<-SQL
|
27
|
+
SELECT
|
28
|
+
m.name as from_table,
|
29
|
+
p."from" as from_column,
|
30
|
+
p."table" as to_table,
|
31
|
+
p."to" as to_column
|
32
|
+
FROM
|
33
|
+
sqlite_master m
|
34
|
+
JOIN pragma_foreign_key_list(m.name) p ON 1
|
35
|
+
WHERE m.type = 'table'
|
36
|
+
ORDER BY m.name ;
|
37
|
+
SQL
|
38
|
+
res.to_a.map{|i| Result.new(i) }
|
39
|
+
end
|
40
|
+
|
25
41
|
def self.get_mysql2_foreign_keys(connection)
|
26
42
|
res = connection.select_all <<-SQL
|
27
43
|
SELECT
|
@@ -57,5 +73,54 @@ module ForeignKeyChecker
|
|
57
73
|
SQL
|
58
74
|
res.to_a.map{ |i| Result.new(i) }
|
59
75
|
end
|
76
|
+
|
77
|
+
def self.get_sqlserver_foreign_keys(connection)
|
78
|
+
res = connection.select_all <<-SQL
|
79
|
+
SELECT obj.name AS FK_NAME,
|
80
|
+
sch.name AS [schema_name],
|
81
|
+
tab1.name AS [from_table],
|
82
|
+
col1.name AS [from_column],
|
83
|
+
tab2.name AS [to_table],
|
84
|
+
col2.name AS [to_column]
|
85
|
+
FROM sys.foreign_key_columns fkc
|
86
|
+
INNER JOIN sys.objects obj
|
87
|
+
ON obj.object_id = fkc.constraint_object_id
|
88
|
+
INNER JOIN sys.tables tab1
|
89
|
+
ON tab1.object_id = fkc.parent_object_id
|
90
|
+
INNER JOIN sys.schemas sch
|
91
|
+
ON tab1.schema_id = sch.schema_id
|
92
|
+
INNER JOIN sys.columns col1
|
93
|
+
ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
|
94
|
+
INNER JOIN sys.tables tab2
|
95
|
+
ON tab2.object_id = fkc.referenced_object_id
|
96
|
+
INNER JOIN sys.columns col2
|
97
|
+
ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
|
98
|
+
SQL
|
99
|
+
res.to_a.map { |i| Result.new(i) }
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.get_tables(model = ActiveRecord::Base)
|
103
|
+
adapter = model.connection_config[:adapter]
|
104
|
+
raise(UnsupportedConnectionAdapter, adapter) unless %w[postgresql mysql2 sqlite3 sqlserver].include?(adapter)
|
105
|
+
|
106
|
+
connection = model.connection
|
107
|
+
send("get_#{adapter}_tables", connection)
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.get_mysql2_tables(connection)
|
111
|
+
connection.select_all("SELECT table_name FROM information_schema.tables WHERE TABLE_SCHEMA = '#{connection.current_database}'").to_a.pluck('table_name')
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.get_postgresql_tables(connection)
|
115
|
+
connection.select_all("SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema'").to_a.pluck('tablename')
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.get_sqlite3_tables(connection)
|
119
|
+
connection.select_all("SELECT name FROM sqlite_master WHERE type='table'").to_a.pluck('name') - ['sqlite_sequence']
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.get_sqlserver_tables(connection)
|
123
|
+
connection.tables
|
124
|
+
end
|
60
125
|
end
|
61
126
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreign_key_checker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AnatolyShirykalov
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -38,6 +38,104 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pg
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mysql2
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: tiny_tds
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: activerecord-sqlserver-adapter
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: irb
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: e2mmap
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: annotate
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
41
139
|
description: Run task to obtain problems with your database
|
42
140
|
email:
|
43
141
|
- pipocavsobake@gmail.com
|
@@ -49,6 +147,8 @@ files:
|
|
49
147
|
- README.md
|
50
148
|
- Rakefile
|
51
149
|
- lib/foreign_key_checker.rb
|
150
|
+
- lib/foreign_key_checker/checkers/relations.rb
|
151
|
+
- lib/foreign_key_checker/checkers/tables.rb
|
52
152
|
- lib/foreign_key_checker/railtie.rb
|
53
153
|
- lib/foreign_key_checker/utils.rb
|
54
154
|
- lib/foreign_key_checker/version.rb
|
@@ -60,7 +160,7 @@ licenses:
|
|
60
160
|
- MIT
|
61
161
|
metadata:
|
62
162
|
allowed_push_host: https://rubygems.org
|
63
|
-
post_install_message:
|
163
|
+
post_install_message:
|
64
164
|
rdoc_options: []
|
65
165
|
require_paths:
|
66
166
|
- lib
|
@@ -75,8 +175,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
175
|
- !ruby/object:Gem::Version
|
76
176
|
version: '0'
|
77
177
|
requirements: []
|
78
|
-
rubygems_version: 3.
|
79
|
-
signing_key:
|
178
|
+
rubygems_version: 3.1.3
|
179
|
+
signing_key:
|
80
180
|
specification_version: 4
|
81
181
|
summary: Find problems with relations in active_record models
|
82
182
|
test_files: []
|