foreign_key_checker 0.1.1 → 0.2.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 +7 -0
- data/Rakefile +0 -10
- data/lib/foreign_key_checker/railtie.rb +3 -0
- data/lib/foreign_key_checker/version.rb +1 -1
- data/lib/foreign_key_checker.rb +35 -2
- data/lib/generators/foreign_key_checker/migration/migration_generator.rb +29 -0
- data/lib/generators/foreign_key_checker/migration/templates/migrations/fix_foreign_keys.rb.erb +13 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b355b8130d2225136101b32202f457ee9615c33621730fa693fcbcb969af3fcf
|
4
|
+
data.tar.gz: ee8b977be65abc39da0914c804f612bb2fb2a33a98a46c922eedde3866147da1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f34d020417ddcaefc15a6faec34ffb495f6383157104b660f28013f85a57d8a390cee15c47613ffed64a884ffc581c4c0c5557c97a36d9e2fadf0ff54021d7a
|
7
|
+
data.tar.gz: a4b0f8032dc6adc78f4780c7c939acc661bb2e9dde713cddee43a5080f59e2882a1433550964f26abb4120491752a83e596f5cc37821561c6ba118cd52f2ad16
|
data/README.md
CHANGED
@@ -5,6 +5,13 @@ This gem checks `belongs_to` ActiveRecord relations. It finds
|
|
5
5
|
3. broken relations: if you try to join such relation (example: `City.joins(:country)`), there is an exception.
|
6
6
|
|
7
7
|
## Usage
|
8
|
+
Generate migration to fix foreign key problems
|
9
|
+
```bash
|
10
|
+
bundle exec rails generate foreign_key_checker:migration
|
11
|
+
```
|
12
|
+
|
13
|
+
|
14
|
+
Print information about foreign key problems
|
8
15
|
```bash
|
9
16
|
bundle exec rake foreign_key_check
|
10
17
|
```
|
data/Rakefile
CHANGED
@@ -4,16 +4,6 @@ rescue LoadError
|
|
4
4
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
5
|
end
|
6
6
|
|
7
|
-
require 'rdoc/task'
|
8
|
-
|
9
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
-
rdoc.rdoc_dir = 'rdoc'
|
11
|
-
rdoc.title = 'ForeignKeyChecker'
|
12
|
-
rdoc.options << '--line-numbers'
|
13
|
-
rdoc.rdoc_files.include('README.md')
|
14
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
-
end
|
16
|
-
|
17
7
|
require 'bundler/gem_tasks'
|
18
8
|
|
19
9
|
require 'rake/testtask'
|
data/lib/foreign_key_checker.rb
CHANGED
@@ -37,9 +37,22 @@ module ForeignKeyChecker
|
|
37
37
|
end
|
38
38
|
|
39
39
|
class ForeignKeyResult < Result
|
40
|
+
attr_reader :scope
|
40
41
|
def message
|
41
42
|
"There is no foreign_key for relation #{human_relation}\n"
|
42
43
|
end
|
44
|
+
|
45
|
+
def migration
|
46
|
+
"add_foreign_key :#{from_table}, :#{to_table}#{
|
47
|
+
", column: :#{from_column}" if from_column.to_s != "#{to_table.singularize}_id"
|
48
|
+
}#{
|
49
|
+
", primary_key: :#{to_column}" if to_column.to_s != 'id'
|
50
|
+
}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_zombie
|
54
|
+
ZombieResult.new(scope: scope, model: model, association: association)
|
55
|
+
end
|
43
56
|
end
|
44
57
|
|
45
58
|
class IndexResult < Result
|
@@ -59,7 +72,26 @@ module ForeignKeyChecker
|
|
59
72
|
from_c = model.connection.quote_column_name(from_column)
|
60
73
|
to_t = model.connection.quote_table_name(to_table)
|
61
74
|
to_c = model.connection.quote_column_name(to_column)
|
62
|
-
"DELETE #{from_t} FROM #{from_t}.#{from_c} LEFT OUTER JOIN #{to_t} ON #{to_t}.#{to_c} = #{from_t}.#{from_c} WHERE #{to_t}.#{to_c} IS NULL"
|
75
|
+
#"DELETE #{from_t} FROM #{from_t}.#{from_c} LEFT OUTER JOIN #{to_t} ON #{to_t}.#{to_c} = #{from_t}.#{from_c} WHERE #{to_t}.#{to_c} IS NULL"
|
76
|
+
"DELETE FROM #{from_t} WHERE #{from_c} IS NOT NULL AND #{from_c} NOT IN (SELECT #{to_c} FROM #{to_t})"
|
77
|
+
end
|
78
|
+
|
79
|
+
def set_null_sql
|
80
|
+
from_t = model.connection.quote_table_name(from_table)
|
81
|
+
from_c = model.connection.quote_column_name(from_column)
|
82
|
+
to_t = model.connection.quote_table_name(to_table)
|
83
|
+
to_c = model.connection.quote_column_name(to_column)
|
84
|
+
#"UPDATE #{from_t} SET #{from_t}.#{from_c} = NULL FROM #{from_t} LEFT OUTER JOIN #{to_t} ON #{to_t}.#{to_c} = #{from_t}.#{from_c} WHERE #{to_t}.#{to_c} IS NULL"
|
85
|
+
"UPDATE #{from_t} SET #{from_c} = NULL WHERE #{from_c} IS NOT NULL AND #{from_c} NOT IN (SELECT #{to_c} FROM #{to_t})"
|
86
|
+
end
|
87
|
+
|
88
|
+
def set_null_migration
|
89
|
+
"execute('#{set_null_sql}')"
|
90
|
+
end
|
91
|
+
|
92
|
+
def migration(set_null: false)
|
93
|
+
return set_null_migration if set_null
|
94
|
+
"execute('#{delete_sql}')"
|
63
95
|
end
|
64
96
|
|
65
97
|
def message
|
@@ -144,7 +176,8 @@ module ForeignKeyChecker
|
|
144
176
|
if foreign_keys && !model.connection.foreign_key_exists?(model.table_name, related.table_name)
|
145
177
|
@result[:foreign_keys] << ForeignKeyResult.new(
|
146
178
|
model: model,
|
147
|
-
association: association
|
179
|
+
association: association,
|
180
|
+
scope: scope,
|
148
181
|
)
|
149
182
|
end
|
150
183
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module ForeignKeyChecker
|
4
|
+
module Generators
|
5
|
+
class MigrationGenerator < ActiveRecord::Generators::Base
|
6
|
+
desc "generates the necessary migrations to fix foreign_key problems"
|
7
|
+
argument :name, type: :string, default: 'FixForeignKeys'
|
8
|
+
|
9
|
+
source_root File.expand_path('templates', __dir__)
|
10
|
+
|
11
|
+
def create_migrations
|
12
|
+
@class_name = name.camelcase.tr(':', '')
|
13
|
+
file_name = name.underscore.tr('/', '_')
|
14
|
+
@done = Dir.glob(Rails.root.join('db', 'migrate', '*.rb')).map do |path|
|
15
|
+
File.open(path).readlines.find { |line| line.include?('ActiveRecord::Migration') && line.include?(@class_name) }
|
16
|
+
end.compact.size
|
17
|
+
@checks = ForeignKeyChecker.check(zombies: false, indexes: false) unless @behavior == :revoke
|
18
|
+
if @behavior == :revoke
|
19
|
+
@file_suffix = "_v#{@done}" if @done > 1
|
20
|
+
@class_suffix = "V#{@done}" if @done > 1
|
21
|
+
else
|
22
|
+
@file_suffix = "_v#{@done + 1}" if @done > 0
|
23
|
+
@class_suffix = "V#{@done + 1}" if @done > 0
|
24
|
+
end
|
25
|
+
migration_template 'migrations/fix_foreign_keys.rb.erb', "db/migrate/#{file_name}#{@file_suffix}.rb"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/generators/foreign_key_checker/migration/templates/migrations/fix_foreign_keys.rb.erb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class <%= @class_name %><%= @class_suffix %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version.to_s %>]
|
2
|
+
def change
|
3
|
+
<% @checks[:foreign_keys].each do |fk| %>
|
4
|
+
reversible do |dir|
|
5
|
+
dir.up do
|
6
|
+
# <%= fk.to_zombie.migration(set_null: true) %>
|
7
|
+
<%= fk.to_zombie.migration %>
|
8
|
+
end
|
9
|
+
end
|
10
|
+
<%= fk.migration %>
|
11
|
+
<% end %>
|
12
|
+
end
|
13
|
+
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.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AnatolyShirykalov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-10-
|
11
|
+
date: 2019-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -51,6 +51,8 @@ files:
|
|
51
51
|
- lib/foreign_key_checker.rb
|
52
52
|
- lib/foreign_key_checker/railtie.rb
|
53
53
|
- lib/foreign_key_checker/version.rb
|
54
|
+
- lib/generators/foreign_key_checker/migration/migration_generator.rb
|
55
|
+
- lib/generators/foreign_key_checker/migration/templates/migrations/fix_foreign_keys.rb.erb
|
54
56
|
- lib/tasks/foreign_key_checker_tasks.rake
|
55
57
|
homepage: https://gitlab.com/pipocavsobake/foreign_key_checker
|
56
58
|
licenses:
|