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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 932660f1dc1e1054ce608b324b8eb2b9dda2f3200b9339106677d7ebf1297b87
4
- data.tar.gz: bf7e22d072393fafe2b3bd65639150448886efd3c5cdd95a3a4617cd4a99023f
3
+ metadata.gz: b355b8130d2225136101b32202f457ee9615c33621730fa693fcbcb969af3fcf
4
+ data.tar.gz: ee8b977be65abc39da0914c804f612bb2fb2a33a98a46c922eedde3866147da1
5
5
  SHA512:
6
- metadata.gz: 2280e4cff60369551661dc1999d11cdfa8c87b994f68360b6c09c05c2acb7619282f4435d0272ef6b2205b56553d14cc401410dd13d05eb1fdb2f224aff07ff5
7
- data.tar.gz: 1fbe7b6fd37d6f97f75c485085c81121213e4a9b450fc8aba300deaabb09f43cdea41899cf6292d4365360be0cd61f327e5415554bf1e5775d28915cba43571d
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'
@@ -3,5 +3,8 @@ module ForeignKeyChecker
3
3
  rake_tasks do
4
4
  load 'tasks/foreign_key_checker_tasks.rake'
5
5
  end
6
+ generators do
7
+ require 'generators/foreign_key_checker/migration/migration_generator.rb'
8
+ end
6
9
  end
7
10
  end
@@ -1,3 +1,3 @@
1
1
  module ForeignKeyChecker
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -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
@@ -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.1.1
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-22 00:00:00.000000000 Z
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: