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 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: