foreign_key_checker 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|