declare_schema 0.1.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -1
  3. data/Gemfile +0 -1
  4. data/Gemfile.lock +1 -3
  5. data/README.md +20 -0
  6. data/Rakefile +13 -20
  7. data/gemfiles/rails_4.gemfile +0 -1
  8. data/gemfiles/rails_5.gemfile +0 -1
  9. data/gemfiles/rails_6.gemfile +0 -1
  10. data/lib/declare_schema/model.rb +27 -24
  11. data/lib/declare_schema/model/field_spec.rb +1 -12
  12. data/lib/declare_schema/version.rb +1 -1
  13. data/lib/generators/declare_schema/migration/migration_generator.rb +20 -14
  14. data/lib/generators/declare_schema/migration/migrator.rb +50 -31
  15. data/lib/generators/declare_schema/migration/templates/migration.rb.erb +1 -1
  16. data/lib/generators/declare_schema/support/eval_template.rb +12 -3
  17. data/lib/generators/declare_schema/support/model.rb +77 -2
  18. data/spec/lib/declare_schema/api_spec.rb +125 -0
  19. data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +8 -4
  20. data/spec/lib/declare_schema/generator_spec.rb +57 -0
  21. data/spec/lib/declare_schema/interactive_primary_key_spec.rb +51 -0
  22. data/spec/lib/declare_schema/migration_generator_spec.rb +795 -0
  23. data/spec/lib/declare_schema/prepare_testapp.rb +31 -0
  24. data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +72 -0
  25. data/spec/spec_helper.rb +26 -0
  26. metadata +11 -12
  27. data/lib/generators/declare_schema/model/templates/model_injection.rb.erb +0 -25
  28. data/test/api.rdoctest +0 -136
  29. data/test/generators.rdoctest +0 -62
  30. data/test/interactive_primary_key.rdoctest +0 -56
  31. data/test/migration_generator.rdoctest +0 -846
  32. data/test/migration_generator_comments.rdoctestDISABLED +0 -74
  33. data/test/prepare_testapp.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5a1596f905dad5d9dd2f08787607c7b9adc742bbb54702bf4cf4aca812e6912
4
- data.tar.gz: 60ec900d6aeb5981d0dd2df7dc689ad01a243e3c1f5b575f33813f5196614c26
3
+ metadata.gz: f3ae0814480b116b32a822887c83612b33458cc910384ae0c2122e547757f141
4
+ data.tar.gz: 133b7bd6d7d91dae9320a4e8002a8591e43ebb97f57013cbe266cef40a169088
5
5
  SHA512:
6
- metadata.gz: b5dc90e36aeb33f00426de19f9df2b85d2bd40754d3bbd6bb8ff8ba410dda808139434d656e305cb9c13320e3cc4130613f06c06ef5abef7e34be4f3ed55e498
7
- data.tar.gz: 39e445fb41afbf2a91dcaa1271040ede91997abcd8e6237616f1e24983d5e88c5aa77c23bcd6c98c9b104f1c8ad68b9456c34a067a807044c2d72893f52e7b3b
6
+ metadata.gz: 77b840eb5feb07d38c4fd96f4212d4c81f19c61a2aa2b4bbffb4f4f11594ba55c30e65ca4b77a68e7b29448f7762dba52782f1845307c5bbc02f7603f080c2e8
7
+ data.tar.gz: 2f85affbd44a6973595883afa01766ede6c950a70c4e783f3064e5c2a59ec5c71a3731d7d484bab133c18c698584077e2c14a8b98c81ce024e2e55bae59dabba
@@ -4,7 +4,32 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
5
  Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [0.1.3] - Unreleased
7
+ ## [0.3.0] - 2020-11-02
8
+ ### Added
9
+ - Added support for `belongs_to optional:`.
10
+ If given, it is passed through to `ActiveRecord`'s `belong_to`.
11
+ If not given in Rails 5+, the `optional:` value is set equal to the `null:` value (default: `false`) and that
12
+ is passed to `ActiveRecord`'s `belong_to`.
13
+ Similarly, if `null:` is not given, it is inferred from `optional:`.
14
+ If both are given, their values are respected, even if contradictory;
15
+ this is a legitimate case when migrating to/from an optional association.
16
+ - Added a new callback `before_generating_migration` to the `Migrator` that can be
17
+ defined in order to custom load more models that might be missed by `eager_load!`
18
+ ### Fixed
19
+ - Migrations are now generated where the `[4.2]` is only applied after `ActiveRecord::Migration` in Rails 5+ (since Rails 4 didn't know about that notation).
20
+
21
+ ## [0.2.0] - 2020-10-26
22
+ ### Added
23
+ - Automatically eager_load! all Rails::Engines before generating migrations.
24
+
25
+ ### Changed
26
+ - Changed tests from rdoctest to rspec.
27
+
28
+ ### Fixed
29
+ - Fixed a bug where `:text limit: 0xffff_ffff` (max size) was omitted from migrations.
30
+ - Fixed a bug where `:bigint` foreign keys were omitted from the migration.
31
+
32
+ ## [0.1.3] - 2020-10-08
8
33
  ### Changed
9
34
  - Updated the `always_ignore_tables` list in `Migrator` to access Rails metadata table names
10
35
  using the appropriate Rails configuration attributes.
@@ -18,6 +43,8 @@ using the appropriate Rails configuration attributes.
18
43
  ### Added
19
44
  - Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
20
45
 
46
+ [0.3.0]: https://github.com/Invoca/declare_schema/compare/v0.2.0...v0.3.0
47
+ [0.2.0]: https://github.com/Invoca/declare_schema/compare/v0.1.3...v0.2.0
21
48
  [0.1.3]: https://github.com/Invoca/declare_schema/compare/v0.1.2...v0.1.3
22
49
  [0.1.2]: https://github.com/Invoca/declare_schema/compare/v0.1.1...v0.1.2
23
50
  [0.1.1]: https://github.com/Invoca/declare_schema/tree/v0.1.1
data/Gemfile CHANGED
@@ -18,6 +18,5 @@ gem 'rails', '~> 5.2', '>= 5.2.4.3'
18
18
  gem 'responders'
19
19
  gem 'rspec'
20
20
  gem 'rubocop'
21
- gem 'rubydoctest'
22
21
  gem 'sqlite3'
23
22
  gem 'yard'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- declare_schema (0.1.3)
4
+ declare_schema (0.3.0)
5
5
  rails (>= 4.2)
6
6
 
7
7
  GEM
@@ -159,7 +159,6 @@ GEM
159
159
  rubocop-ast (0.4.2)
160
160
  parser (>= 2.7.1.4)
161
161
  ruby-progressbar (1.10.1)
162
- rubydoctest (1.1.5)
163
162
  sprockets (4.0.2)
164
163
  concurrent-ruby (~> 1.0)
165
164
  rack (> 1, < 3)
@@ -194,7 +193,6 @@ DEPENDENCIES
194
193
  responders
195
194
  rspec
196
195
  rubocop
197
- rubydoctest
198
196
  sqlite3
199
197
  yard
200
198
 
data/README.md CHANGED
@@ -50,6 +50,26 @@ Migration filename: [<enter>=declare_schema_migration_1|<custom_name>]: add_comp
50
50
  ```
51
51
  Note that the migration generator is interactive -- it can't tell the difference between renaming something vs. adding one thing and removing another, so sometimes it will ask you to clarify.
52
52
 
53
+ ## Migrator Configuration
54
+
55
+ The following configuration options are available for the gem and can be used
56
+ during the initialization of your Rails application.
57
+
58
+ ### before_generating_migration callback
59
+
60
+ During the initializtion process for generating migrations, `DeclareSchema` will
61
+ trigger the `eager_load!` on the `Rails` application and all `Rails::Engine`s loaded
62
+ into scope. If you need to generate migrations for models that aren't automatically loaded by `eager_load!`,
63
+ load them in the `before_generating_migration` block.
64
+
65
+ **Example Configuration**
66
+
67
+ ```ruby
68
+ DeclareSchema::Migration::Migrator.before_generating_migration do
69
+ require 'lib/some/hidden/models.rb'
70
+ end
71
+ ```
72
+
53
73
  ## Installing
54
74
 
55
75
  Install the `DeclareSchema` gem directly:
data/Rakefile CHANGED
@@ -14,7 +14,6 @@ $LOAD_PATH.unshift File.expand_path('lib', __dir__)
14
14
  require 'declare_schema'
15
15
 
16
16
  RUBY = 'ruby'
17
- RUBYDOCTEST = ENV['RUBYDOCTEST'] || "#{RUBY} -S rubydoctest"
18
17
  GEM_ROOT = __dir__
19
18
  TESTAPP_PATH = ENV['TESTAPP_PATH'] || File.join(Dir.tmpdir, 'declare_schema_testapp')
20
19
  BIN = File.expand_path('bin/declare_schema', __dir__)
@@ -24,13 +23,7 @@ task default: 'test:all'
24
23
  include Rake::DSL
25
24
 
26
25
  namespace "test" do
27
- task all: [:doctest, :spec]
28
-
29
- desc "Run the doctests"
30
- task :doctest do |_t|
31
- files = Dir['test/*.rdoctest'].sort.map { |f| File.expand_path(f) }.join(' ')
32
- system("#{RUBYDOCTEST} --trace --verbose #{files}") or exit(1)
33
- end
26
+ task all: :spec
34
27
 
35
28
  desc "Prepare a rails application for testing"
36
29
  task :prepare_testapp, :force do |_t, args|
@@ -38,19 +31,19 @@ namespace "test" do
38
31
  FileUtils.remove_entry_secure(TESTAPP_PATH, true)
39
32
  sh %(#{BIN} new #{TESTAPP_PATH} --skip-wizard --skip-bundle)
40
33
  FileUtils.chdir TESTAPP_PATH
41
- sh %(bundle install)
42
- sh %(echo "" >> Gemfile)
43
- sh %(echo "gem 'irt', :group => :development" >> Gemfile) # to make the bundler happy
44
- sh %(echo "gem 'therubyracer'" >> Gemfile)
45
- sh %(echo "gem 'kramdown'" >> Gemfile)
46
- sh %(echo "" > app/models/.gitignore) # because git reset --hard would rm the dir
47
- rm %(.gitignore) # we need to reset everything in a testapp
48
- sh %(git init && git add . && git commit -m "initial commit")
49
- puts %(The testapp has been created in '#{TESTAPP_PATH}')
34
+ sh "bundle install"
35
+ sh "(echo '';
36
+ echo \"gem 'irt', :group => :development\";
37
+ echo \"gem 'therubyracer'\";
38
+ echo \"gem 'kramdown'\") > Gemfile"
39
+ sh "echo '' > app/models/.gitignore" # because git reset --hard would rm the dir
40
+ rm ".gitignore" # we need to reset everything in a testapp
41
+ sh "git init && git add . && git commit -m \"initial commit\""
42
+ puts "The testapp has been created in '#{TESTAPP_PATH}'"
50
43
  else
51
- FileUtils.chdir TESTAPP_PATH
52
- sh %(git add .)
53
- sh %(git reset --hard -q HEAD)
44
+ FileUtils.chdir(TESTAPP_PATH)
45
+ sh "git add ."
46
+ sh "git reset --hard -q HEAD"
54
47
  end
55
48
  end
56
49
  end
@@ -11,7 +11,6 @@ gem "rails", "~> 4.2"
11
11
  gem "responders"
12
12
  gem "rspec"
13
13
  gem "rubocop"
14
- gem "rubydoctest"
15
14
  gem "sqlite3", "~> 1.3.0"
16
15
  gem "yard"
17
16
 
@@ -11,7 +11,6 @@ gem "rails", "~> 5.2"
11
11
  gem "responders"
12
12
  gem "rspec"
13
13
  gem "rubocop"
14
- gem "rubydoctest"
15
14
  gem "sqlite3"
16
15
  gem "yard"
17
16
 
@@ -11,7 +11,6 @@ gem "rails", "~> 6.0"
11
11
  gem "responders"
12
12
  gem "rspec"
13
13
  gem "rubocop"
14
- gem "rubydoctest"
15
14
  gem "sqlite3"
16
15
  gem "yard"
17
16
 
@@ -106,18 +106,14 @@ module DeclareSchema
106
106
  end
107
107
 
108
108
  # Extend belongs_to so that it creates a FieldSpec for the foreign key
109
- def belongs_to(name, *args, &block)
110
- if args.size == 0 || (args.size == 1 && args[0].is_a?(Proc))
111
- options = {}
112
- args.push(options)
113
- elsif args.size == 1
114
- options = args[0]
115
- else
116
- options = args[1]
117
- end
109
+ def belongs_to(name, scope = nil, **options, &block)
118
110
  column_options = {}
119
- column_options[:null] = options.delete(:null) || false
120
- column_options[:comment] = options.delete(:comment) if options.has_key?(:comment)
111
+
112
+ column_options[:null] = if options.has_key?(:null)
113
+ options.delete(:null)
114
+ elsif options.has_key?(:optional)
115
+ options[:optional] # infer :null from :optional
116
+ end || false
121
117
  column_options[:default] = options.delete(:default) if options.has_key?(:default)
122
118
  column_options[:limit] = options.delete(:limit) if options.has_key?(:limit)
123
119
 
@@ -130,20 +126,27 @@ module DeclareSchema
130
126
  fk_options[:constraint_name] = options.delete(:constraint) if options.has_key?(:constraint)
131
127
  fk_options[:index_name] = index_options[:name]
132
128
 
129
+ fk = options[:foreign_key]&.to_s || "#{name}_id"
130
+
131
+ if !options.has_key?(:optional) && Rails::VERSION::MAJOR >= 5
132
+ options[:optional] = column_options[:null] # infer :optional from :null
133
+ end
134
+
133
135
  fk_options[:dependent] = options.delete(:far_end_dependent) if options.has_key?(:far_end_dependent)
134
- super(name, *args, &block).tap do |_bt|
135
- refl = reflections[name.to_s] or raise "Couldn't find reflection #{name} in #{reflections.keys}"
136
- fkey = refl.foreign_key
137
- declare_field(fkey.to_sym, :integer, column_options)
138
- if refl.options[:polymorphic]
139
- foreign_type = options[:foreign_type] || "#{name}_type"
140
- declare_polymorphic_type_field(foreign_type, column_options)
141
- index([foreign_type, fkey], index_options) if index_options[:name] != false
142
- else
143
- index(fkey, index_options) if index_options[:name] != false
144
- options[:constraint_name] = options
145
- constraint(fkey, fk_options) if fk_options[:constraint_name] != false
146
- end
136
+
137
+ super(name, scope, options)
138
+
139
+ refl = reflections[name.to_s] or raise "Couldn't find reflection #{name} in #{reflections.keys}"
140
+ fkey = refl.foreign_key or raise "Couldn't find foreign_key for #{name} in #{refl.inspect}"
141
+ declare_field(fkey.to_sym, :integer, column_options)
142
+ if refl.options[:polymorphic]
143
+ foreign_type = options[:foreign_type] || "#{name}_type"
144
+ declare_polymorphic_type_field(foreign_type, column_options)
145
+ index([foreign_type, fkey], index_options) if index_options[:name] != false
146
+ else
147
+ index(fkey, index_options) if index_options[:name] != false
148
+ options[:constraint_name] = options
149
+ constraint(fkey, fk_options) if fk_options[:constraint_name] != false
147
150
  end
148
151
  end
149
152
 
@@ -53,7 +53,7 @@ module DeclareSchema
53
53
  @options[:limit] = self.class.round_up_mysql_text_limit(@options[:limit] || MYSQL_LONGTEXT_LIMIT)
54
54
  end
55
55
  when :string
56
- @options[:limit] or raise "limit must be given for :string field #{model}##{@name}: #{@options.inspect}; do you want 255?"
56
+ @options[:limit] or raise "limit must be given for :string field #{model}##{@name}: #{@options.inspect}; do you want `limit: 255`?"
57
57
  end
58
58
  @position = position_option || model.field_specs.length
59
59
  end
@@ -102,10 +102,6 @@ module DeclareSchema
102
102
  @options[:default]
103
103
  end
104
104
 
105
- def comment
106
- @options[:comment]
107
- end
108
-
109
105
  def same_type?(col_spec)
110
106
  type = sql_type
111
107
  normalized_type = TYPE_SYNONYMS[type] || type
@@ -115,13 +111,6 @@ module DeclareSchema
115
111
 
116
112
  def different_to?(col_spec)
117
113
  !same_type?(col_spec) ||
118
- # we should be able to use col_spec.comment, but col_spec has
119
- # a nil table_name for some strange reason.
120
- (model.table_exists? &&
121
- ActiveRecord::Base.respond_to?(:column_comment) &&
122
- !(col_comment = ActiveRecord::Base.column_comment(col_spec.name, model.table_name)).nil? &&
123
- col_comment != comment
124
- ) ||
125
114
  begin
126
115
  native_type = native_types[type]
127
116
  check_attributes = [:null, :default]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeclareSchema
4
- VERSION = "0.1.3"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -3,7 +3,7 @@
3
3
  require 'rails/generators/migration'
4
4
  require 'rails/generators/active_record'
5
5
  require 'generators/declare_schema/support/thor_shell'
6
- require_relative '../../../declare_schema/model/field_spec'
6
+ require 'declare_schema/model/field_spec'
7
7
 
8
8
  module DeclareSchema
9
9
  class MigrationGenerator < Rails::Generators::Base
@@ -86,7 +86,7 @@ module DeclareSchema
86
86
  @down = down
87
87
  @migration_class_name = final_migration_name.camelize
88
88
 
89
- migration_template 'migration.rb.erb', "db/migrate/#{final_migration_name.underscore}.rb"
89
+ migration_template('migration.rb.erb', "db/migrate/#{final_migration_name.underscore}.rb")
90
90
  if action == 'm'
91
91
  case Rails::VERSION::MAJOR
92
92
  when 4
@@ -118,14 +118,13 @@ module DeclareSchema
118
118
  ActiveRecord::Migrator.new(:up, migrations, ActiveRecord::SchemaMigration).pending_migrations
119
119
  end
120
120
 
121
- if pending_migrations.any?
122
- say "You have #{pending_migrations.size} pending migration#{'s' if pending_migrations.size > 1}:"
123
- pending_migrations.each do |pending_migration|
124
- say format(' %4d %s', pending_migration.version, pending_migration.name)
121
+ pending_migrations.any?.tap do |any|
122
+ if any
123
+ say "You have #{pending_migrations.size} pending migration#{'s' if pending_migrations.size > 1}:"
124
+ pending_migrations.each do |pending_migration|
125
+ say format(' %4d %s', pending_migration.version, pending_migration.name)
126
+ end
125
127
  end
126
- true
127
- else
128
- false
129
128
  end
130
129
  end
131
130
 
@@ -139,10 +138,10 @@ module DeclareSchema
139
138
  loop do
140
139
  if rename_to_choices.empty?
141
140
  say "\nCONFIRM DROP! #{kind_str} #{name_prefix}#{t}"
142
- resp = ask("Enter 'drop #{t}' to confirm or press enter to keep:")
143
- if resp.strip == "drop #{t}"
141
+ resp = ask("Enter 'drop #{t}' to confirm or press enter to keep:").strip
142
+ if resp == "drop #{t}"
144
143
  break
145
- elsif resp.strip.empty?
144
+ elsif resp.empty?
146
145
  to_drop.delete(t)
147
146
  break
148
147
  else
@@ -151,8 +150,7 @@ module DeclareSchema
151
150
  else
152
151
  say "\nDROP, RENAME or KEEP?: #{kind_str} #{name_prefix}#{t}"
153
152
  say "Rename choices: #{to_create * ', '}"
154
- resp = ask "Enter either 'drop #{t}' or one of the rename choices or press enter to keep:"
155
- resp = resp.strip
153
+ resp = ask("Enter either 'drop #{t}' or one of the rename choices or press enter to keep:").strip
156
154
 
157
155
  if resp == "drop #{t}"
158
156
  # Leave things as they are
@@ -183,3 +181,11 @@ module DeclareSchema
183
181
  end
184
182
  end
185
183
  end
184
+
185
+ module Generators
186
+ module DeclareSchema
187
+ module Migration
188
+ MigrationGenerator = ::DeclareSchema::MigrationGenerator
189
+ end
190
+ end
191
+ end
@@ -69,12 +69,14 @@ module Generators
69
69
  class Migrator
70
70
  class Error < RuntimeError; end
71
71
 
72
- @ignore_models = []
73
- @ignore_tables = []
74
- @active_record_class = ActiveRecord::Base
72
+ @ignore_models = []
73
+ @ignore_tables = []
74
+ @before_generating_migration_callback = nil
75
+ @active_record_class = ActiveRecord::Base
75
76
 
76
77
  class << self
77
78
  attr_accessor :ignore_models, :ignore_tables, :disable_indexing, :disable_constraints, :active_record_class
79
+ attr_reader :before_generating_migration_callback
78
80
 
79
81
  def active_record_class
80
82
  @active_record_class.is_a?(Class) or @active_record_class = @active_record_class.to_s.constantize
@@ -96,6 +98,25 @@ module Generators
96
98
  def connection
97
99
  ActiveRecord::Base.connection
98
100
  end
101
+
102
+ def fix_native_types(types)
103
+ case connection.class.name
104
+ when /mysql/i
105
+ types[:integer][:limit] ||= 11
106
+ types[:text][:limit] ||= 0xffff
107
+ types[:binary][:limit] ||= 0xffff
108
+ end
109
+ types
110
+ end
111
+
112
+ def native_types
113
+ @native_types ||= fix_native_types(connection.native_database_types)
114
+ end
115
+
116
+ def before_generating_migration(&block)
117
+ block or raise ArgumentError, 'A block is required when setting the before_generating_migration callback'
118
+ @before_generating_migration_callback = block
119
+ end
99
120
  end
100
121
 
101
122
  def initialize(ambiguity_resolver = {})
@@ -107,36 +128,26 @@ module Generators
107
128
  attr_accessor :renames
108
129
 
109
130
  def load_rails_models
131
+ ActiveRecord::Migration.verbose = false
132
+
110
133
  Rails.application.eager_load!
134
+ Rails::Engine.subclasses.each(&:eager_load!)
135
+ self.class.before_generating_migration_callback&.call
111
136
  end
112
137
 
113
138
  # Returns an array of model classes that *directly* extend
114
139
  # ActiveRecord::Base, excluding anything in the CGI module
115
140
  def table_model_classes
116
141
  load_rails_models
117
- ActiveRecord::Base.send(:descendants).reject { |c| (c.base_class != c) || c.name.starts_with?("CGI::") }
142
+ ActiveRecord::Base.send(:descendants).select do |klass|
143
+ klass.base_class == klass && !klass.name.starts_with?("CGI::")
144
+ end
118
145
  end
119
146
 
120
147
  def connection
121
148
  self.class.connection
122
149
  end
123
150
 
124
- class << self
125
- def fix_native_types(types)
126
- case connection.class.name
127
- when /mysql/i
128
- types[:integer][:limit] ||= 11
129
- types[:text][:limit] ||= 0xffff
130
- types[:binary][:limit] ||= 0xffff
131
- end
132
- types
133
- end
134
-
135
- def native_types
136
- @native_types ||= fix_native_types(connection.native_database_types)
137
- end
138
- end
139
-
140
151
  def native_types
141
152
  self.class.native_types
142
153
  end
@@ -217,7 +228,7 @@ module Generators
217
228
  end
218
229
  end
219
230
 
220
- def always_ignore_tables
231
+ def self.always_ignore_tables
221
232
  sessions_table =
222
233
  begin
223
234
  if defined?(CGI::Session::ActiveRecordStore::Session) &&
@@ -231,8 +242,8 @@ module Generators
231
242
 
232
243
  [
233
244
  'schema_info',
234
- ActiveRecord::Base.schema_migrations_table_name,
235
- ActiveRecord::Base.internal_metadata_table_name,
245
+ ActiveRecord::Base.try(:schema_migrations_table_name) || 'schema_migrations',
246
+ ActiveRecord::Base.try(:internal_metadata_table_name) || 'ar_internal_metadata',
236
247
  sessions_table
237
248
  ].compact
238
249
  end
@@ -256,7 +267,7 @@ module Generators
256
267
  model_table_names = models_by_table_name.keys
257
268
 
258
269
  to_create = model_table_names - db_tables
259
- to_drop = db_tables - model_table_names - always_ignore_tables
270
+ to_drop = db_tables - model_table_names - self.class.always_ignore_tables
260
271
  to_change = model_table_names
261
272
  to_rename = extract_table_renames!(to_create, to_drop)
262
273
 
@@ -404,14 +415,13 @@ module Generators
404
415
  spec = model.field_specs[c]
405
416
  if spec.different_to?(col) # TODO: DRY this up to a diff function that returns the differences. It's different if it has differences. -Colin
406
417
  change_spec = fk_field_options(model, c)
407
- change_spec[:limit] = spec.limit if (spec.sql_type != :text ||
418
+ change_spec[:limit] ||= spec.limit if (spec.sql_type != :text ||
408
419
  ::DeclareSchema::Model::FieldSpec.mysql_text_limits?) &&
409
420
  (spec.limit || col.limit)
410
421
  change_spec[:precision] = spec.precision unless spec.precision.nil?
411
422
  change_spec[:scale] = spec.scale unless spec.scale.nil?
412
423
  change_spec[:null] = spec.null unless spec.null && col.null
413
424
  change_spec[:default] = spec.default unless spec.default.nil? && col.default.nil?
414
- change_spec[:comment] = spec.comment unless spec.comment.nil? && (col.comment if col.respond_to?(:comment)).nil?
415
425
 
416
426
  changes << "change_column :#{new_table_name}, :#{c}, " +
417
427
  ([":#{spec.sql_type}"] + format_options(change_spec, spec.sql_type, changing: true)).join(", ")
@@ -511,8 +521,7 @@ module Generators
511
521
  next if k == :null && v == true
512
522
  end
513
523
 
514
- next if k == :limit && type == :text &&
515
- (!::DeclareSchema::Model::FieldSpec.mysql_text_limits? || v == ::DeclareSchema::Model::FieldSpec::MYSQL_LONGTEXT_LIMIT)
524
+ next if k == :limit && type == :text && !::DeclareSchema::Model::FieldSpec.mysql_text_limits?
516
525
 
517
526
  if k.is_a?(Symbol)
518
527
  "#{k}: #{v.inspect}"
@@ -523,10 +532,20 @@ module Generators
523
532
  end
524
533
 
525
534
  def fk_field_options(model, field_name)
526
- if (foreign_key = model.constraint_specs.find { |fk| field_name == fk.foreign_key.to_s }) && (parent_table = foreign_key.parent_table_name)
535
+ foreign_key = model.constraint_specs.find { |fk| field_name == fk.foreign_key.to_s }
536
+ if foreign_key && (parent_table = foreign_key.parent_table_name)
527
537
  parent_columns = connection.columns(parent_table) rescue []
528
- pk_column = parent_columns.find { |column| column.name == "id" } # right now foreign keys assume id is the target
529
- pk_limit = pk_column ? pk_column.cast_type.limit : 8
538
+ pk_limit =
539
+ if (pk_column = parent_columns.find { |column| column.name.to_s == "id" }) # right now foreign keys assume id is the target
540
+ if Rails::VERSION::MAJOR <= 4
541
+ pk_column.cast_type.limit
542
+ else
543
+ pk_column.limit
544
+ end
545
+ else
546
+ 8
547
+ end
548
+
530
549
  { limit: pk_limit }
531
550
  else
532
551
  {}