declare_schema 0.1.3 → 0.3.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.
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
  {}