declare_schema 0.10.0 → 0.12.0.pre.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +16 -6
  5. data/lib/declare_schema.rb +12 -1
  6. data/lib/declare_schema/extensions/active_record/fields_declaration.rb +4 -2
  7. data/lib/declare_schema/model.rb +59 -15
  8. data/lib/declare_schema/model/column.rb +2 -2
  9. data/lib/declare_schema/model/field_spec.rb +4 -4
  10. data/lib/declare_schema/model/foreign_key_definition.rb +6 -11
  11. data/lib/declare_schema/model/habtm_model_shim.rb +2 -2
  12. data/lib/declare_schema/model/index_definition.rb +8 -25
  13. data/lib/declare_schema/schema_change/all.rb +22 -0
  14. data/lib/declare_schema/schema_change/base.rb +45 -0
  15. data/lib/declare_schema/schema_change/column_add.rb +27 -0
  16. data/lib/declare_schema/schema_change/column_change.rb +32 -0
  17. data/lib/declare_schema/schema_change/column_remove.rb +20 -0
  18. data/lib/declare_schema/schema_change/column_rename.rb +23 -0
  19. data/lib/declare_schema/schema_change/foreign_key_add.rb +25 -0
  20. data/lib/declare_schema/schema_change/foreign_key_remove.rb +20 -0
  21. data/lib/declare_schema/schema_change/index_add.rb +33 -0
  22. data/lib/declare_schema/schema_change/index_remove.rb +20 -0
  23. data/lib/declare_schema/schema_change/primary_key_change.rb +33 -0
  24. data/lib/declare_schema/schema_change/table_add.rb +37 -0
  25. data/lib/declare_schema/schema_change/table_change.rb +36 -0
  26. data/lib/declare_schema/schema_change/table_remove.rb +22 -0
  27. data/lib/declare_schema/schema_change/table_rename.rb +22 -0
  28. data/lib/declare_schema/version.rb +1 -1
  29. data/lib/generators/declare_schema/migration/USAGE +14 -24
  30. data/lib/generators/declare_schema/migration/migration_generator.rb +40 -38
  31. data/lib/generators/declare_schema/migration/migrator.rb +190 -187
  32. data/lib/generators/declare_schema/migration/templates/migration.rb.erb +3 -3
  33. data/spec/lib/declare_schema/api_spec.rb +3 -1
  34. data/spec/lib/declare_schema/field_spec_spec.rb +3 -3
  35. data/spec/lib/declare_schema/generator_spec.rb +2 -2
  36. data/spec/lib/declare_schema/interactive_primary_key_spec.rb +60 -25
  37. data/spec/lib/declare_schema/migration_generator_spec.rb +471 -377
  38. data/spec/lib/declare_schema/model/column_spec.rb +2 -6
  39. data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +28 -16
  40. data/spec/lib/declare_schema/model/habtm_model_shim_spec.rb +4 -6
  41. data/spec/lib/declare_schema/model/index_definition_spec.rb +4 -4
  42. data/spec/lib/declare_schema/schema_change/base_spec.rb +75 -0
  43. data/spec/lib/declare_schema/schema_change/column_add_spec.rb +30 -0
  44. data/spec/lib/declare_schema/schema_change/column_change_spec.rb +33 -0
  45. data/spec/lib/declare_schema/schema_change/column_remove_spec.rb +30 -0
  46. data/spec/lib/declare_schema/schema_change/column_rename_spec.rb +28 -0
  47. data/spec/lib/declare_schema/schema_change/foreign_key_add_spec.rb +29 -0
  48. data/spec/lib/declare_schema/schema_change/foreign_key_remove_spec.rb +29 -0
  49. data/spec/lib/declare_schema/schema_change/index_add_spec.rb +56 -0
  50. data/spec/lib/declare_schema/schema_change/index_remove_spec.rb +29 -0
  51. data/spec/lib/declare_schema/schema_change/primary_key_change_spec.rb +69 -0
  52. data/spec/lib/declare_schema/schema_change/table_add_spec.rb +50 -0
  53. data/spec/lib/declare_schema/schema_change/table_change_spec.rb +30 -0
  54. data/spec/lib/declare_schema/schema_change/table_remove_spec.rb +27 -0
  55. data/spec/lib/declare_schema/schema_change/table_rename_spec.rb +27 -0
  56. data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +59 -11
  57. data/spec/spec_helper.rb +1 -1
  58. data/spec/support/acceptance_spec_helpers.rb +2 -2
  59. metadata +34 -5
@@ -1,9 +1,9 @@
1
- class <%= @migration_class_name %> < (Rails::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)
1
+ class <%= @migration_class_name %> < (ActiveSupport::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)
2
2
  def self.up
3
- <%= @up %>
3
+ <%= @up.presence or raise "no @up given!" %>
4
4
  end
5
5
 
6
6
  def self.down
7
- <%= @down %>
7
+ <%= @down.presence or raise "no @down given!" %>
8
8
  end
9
9
  end
@@ -39,12 +39,14 @@ RSpec.describe 'DeclareSchema API' do
39
39
 
40
40
  load_models
41
41
 
42
- if Rails::VERSION::MAJOR == 5
42
+ if ActiveSupport::VERSION::MAJOR == 5
43
43
  # TODO: get this to work on Travis for Rails 6
44
+ # TODO: uncomment since we're not on Travis any more? -Colin
44
45
  generate_migrations '-n', '-m'
45
46
  end
46
47
 
47
48
  require 'advert'
49
+ Advert.reset_primary_key
48
50
 
49
51
  ## The Basics
50
52
 
@@ -6,13 +6,13 @@ rescue LoadError
6
6
  end
7
7
 
8
8
  RSpec.describe DeclareSchema::Model::FieldSpec do
9
- let(:model) { double('model', table_options: {}, _defined_primary_key: 'id') }
9
+ let(:model) { double('model', _table_options: {}, _declared_primary_key: 'id') }
10
10
  let(:col_spec) { double('col_spec', type: :string) }
11
11
 
12
12
  before do
13
13
  load File.expand_path('prepare_testapp.rb', __dir__)
14
14
 
15
- if Rails::VERSION::MAJOR < 5
15
+ if ActiveSupport::VERSION::MAJOR < 5
16
16
  allow(col_spec).to receive(:type_cast_from_database, &:itself)
17
17
  end
18
18
  end
@@ -184,7 +184,7 @@ RSpec.describe DeclareSchema::Model::FieldSpec do
184
184
 
185
185
  describe '#schema_attributes' do
186
186
  let(:col_spec) do
187
- case Rails::VERSION::MAJOR
187
+ case ActiveSupport::VERSION::MAJOR
188
188
  when 4
189
189
  cast_type = ActiveRecord::Type::Integer.new(limit: 8)
190
190
  ActiveRecord::ConnectionAdapters::Column.new("price", nil, cast_type, "integer(8)", false)
@@ -27,7 +27,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
27
27
  end
28
28
  EOS
29
29
 
30
- case Rails::VERSION::MAJOR
30
+ case ActiveSupport::VERSION::MAJOR
31
31
  when 4, 5
32
32
  expect_test_definition_to_eq('alpha/beta', <<~EOS)
33
33
  require "test_helper"
@@ -50,7 +50,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
50
50
  EOS
51
51
  end
52
52
 
53
- case Rails::VERSION::MAJOR
53
+ case ActiveSupport::VERSION::MAJOR
54
54
  when 4
55
55
  expect_test_fixture_to_eq('alpha/beta', <<~EOS)
56
56
  # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rails'
4
3
  begin
5
4
  require 'mysql2'
6
5
  rescue LoadError
@@ -20,7 +19,7 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
20
19
  end
21
20
 
22
21
  generate_migrations '-n', '-m'
23
- expect(Foo._defined_primary_key).to eq('foo_id')
22
+ expect(Foo._declared_primary_key).to eq('foo_id')
24
23
 
25
24
  ### migrate from
26
25
  # rename from custom primary_key
@@ -32,13 +31,38 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
32
31
 
33
32
  allow_any_instance_of(DeclareSchema::Support::ThorShell).to receive(:ask).with(/one of the rename choices or press enter to keep/) { 'id' }
34
33
  generate_migrations '-n', '-m'
35
- expect(Foo._defined_primary_key).to eq('id')
34
+ expect(Foo._declared_primary_key).to eq('id')
36
35
 
37
36
  nuke_model_class(Foo)
38
37
 
39
- ### migrate to
38
+ # The ActiveRecord sqlite3 driver has a bug where rename_column recreates the entire table, but forgets to set the primary key:
39
+ #
40
+ # [7] pry(#<RSpec::ExampleGroups::DeclareSchemaMigrationGeneratorInteractivePrimaryKey>)> u = 'rename_column :foos, :foo_id, :id'
41
+ # => "rename_column :foos, :foo_id, :id"
42
+ # [8] pry(#<RSpec::ExampleGroups::DeclareSchemaMigrationGeneratorInteractivePrimaryKey>)> ActiveRecord::Migration.class_eval(u)
43
+ # (0.0ms) begin transaction
44
+ # (pry):17
45
+ # (0.2ms) CREATE TEMPORARY TABLE "afoos" ("id" integer NOT NULL)
46
+ # (pry):17
47
+ # (0.1ms) INSERT INTO "afoos" ("id")
48
+ #
49
+ # (pry):17
50
+ # (0.4ms) DROP TABLE "foos"
51
+ # (pry):17
52
+ # (0.1ms) CREATE TABLE "foos" ("id" integer NOT NULL)
53
+ # (pry):17
54
+ # (0.1ms) INSERT INTO "foos" ("id")
55
+ #
56
+ # (pry):17
57
+ # (0.1ms) DROP TABLE "afoos"
58
+ # (pry):17
59
+ # (0.9ms) commit transaction
60
+ if defined?(SQLite3)
61
+ ActiveRecord::Base.connection.execute("drop table foos")
62
+ ActiveRecord::Base.connection.execute("CREATE TABLE foos (id integer PRIMARY KEY AUTOINCREMENT NOT NULL)")
63
+ end
40
64
 
41
- if Rails::VERSION::MAJOR >= 5 && !defined?(Mysql2) # TODO TECH-4814 Put this test back for Mysql2
65
+ if ActiveSupport::VERSION::MAJOR >= 5 && !defined?(Mysql2) # TODO TECH-4814 Put this test back for Mysql2
42
66
  # replace custom primary_key
43
67
  class Foo < ActiveRecord::Base
44
68
  fields do
@@ -48,13 +72,7 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
48
72
 
49
73
  allow_any_instance_of(DeclareSchema::Support::ThorShell).to receive(:ask).with(/one of the rename choices or press enter to keep/) { 'drop id' }
50
74
  generate_migrations '-n', '-m'
51
- expect(Foo._defined_primary_key).to eq('foo_id')
52
-
53
- ### ensure it doesn't cause further migrations
54
-
55
- # check no further migrations
56
- up = Generators::DeclareSchema::Migration::Migrator.run.first
57
- expect(up).to eq("")
75
+ expect(Foo._declared_primary_key).to eq('foo_id')
58
76
  end
59
77
  end
60
78
  end
@@ -62,8 +80,7 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
62
80
  context 'Using declare_schema' do
63
81
  it "allows alternate primary keys" do
64
82
  class Foo < ActiveRecord::Base
65
- declare_schema do
66
- end
83
+ declare_schema { }
67
84
  self.primary_key = "foo_id"
68
85
  end
69
86
 
@@ -73,21 +90,45 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
73
90
  ### migrate from
74
91
  # rename from custom primary_key
75
92
  class Foo < ActiveRecord::Base
76
- declare_schema do
77
- end
93
+ declare_schema { }
78
94
  self.primary_key = "id"
79
95
  end
80
96
 
81
97
  puts "\n\e[45m Please enter 'id' (no quotes) at the next prompt \e[0m"
82
98
  allow_any_instance_of(DeclareSchema::Support::ThorShell).to receive(:ask).with(/one of the rename choices or press enter to keep/) { 'id' }
83
99
  generate_migrations '-n', '-m'
84
- expect(Foo.primary_key).to eq('id')
100
+ expect(Foo._declared_primary_key).to eq('id')
85
101
 
86
102
  nuke_model_class(Foo)
87
103
 
88
- ### migrate to
104
+ # The ActiveRecord sqlite3 driver has a bug where rename_column recreates the entire table, but forgets to set the primary key:
105
+ #
106
+ # [7] pry(#<RSpec::ExampleGroups::DeclareSchemaMigrationGeneratorInteractivePrimaryKey>)> u = 'rename_column :foos, :foo_id, :id'
107
+ # => "rename_column :foos, :foo_id, :id"
108
+ # [8] pry(#<RSpec::ExampleGroups::DeclareSchemaMigrationGeneratorInteractivePrimaryKey>)> ActiveRecord::Migration.class_eval(u)
109
+ # (0.0ms) begin transaction
110
+ # (pry):17
111
+ # (0.2ms) CREATE TEMPORARY TABLE "afoos" ("id" integer NOT NULL)
112
+ # (pry):17
113
+ # (0.1ms) INSERT INTO "afoos" ("id")
114
+ #
115
+ # (pry):17
116
+ # (0.4ms) DROP TABLE "foos"
117
+ # (pry):17
118
+ # (0.1ms) CREATE TABLE "foos" ("id" integer NOT NULL)
119
+ # (pry):17
120
+ # (0.1ms) INSERT INTO "foos" ("id")
121
+ #
122
+ # (pry):17
123
+ # (0.1ms) DROP TABLE "afoos"
124
+ # (pry):17
125
+ # (0.9ms) commit transaction
126
+ if defined?(SQLite3)
127
+ ActiveRecord::Base.connection.execute("drop table foos")
128
+ ActiveRecord::Base.connection.execute("CREATE TABLE foos (id integer PRIMARY KEY AUTOINCREMENT NOT NULL)")
129
+ end
89
130
 
90
- if Rails::VERSION::MAJOR >= 5 && !defined?(Mysql2) # TODO TECH-4814 Put this test back for Mysql2
131
+ if ActiveSupport::VERSION::MAJOR >= 5 && !defined?(Mysql2) # TODO TECH-4814 Put this test back for Mysql2
91
132
  # replace custom primary_key
92
133
  class Foo < ActiveRecord::Base
93
134
  declare_schema do
@@ -99,12 +140,6 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
99
140
  allow_any_instance_of(DeclareSchema::Support::ThorShell).to receive(:ask).with(/one of the rename choices or press enter to keep/) { 'drop id' }
100
141
  generate_migrations '-n', '-m'
101
142
  expect(Foo.primary_key).to eq('foo_id')
102
-
103
- ### ensure it doesn't cause further migrations
104
-
105
- # check no further migrations
106
- up = Generators::DeclareSchema::Migration::Migrator.run.first
107
- expect(up).to eq("")
108
143
  end
109
144
  end
110
145
  end
@@ -1,25 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rails'
4
3
  begin
5
4
  require 'mysql2'
6
5
  rescue LoadError
7
6
  end
8
7
 
8
+ begin
9
+ require 'sqlite3'
10
+ rescue LoadError
11
+ end
12
+
9
13
  RSpec.describe 'DeclareSchema Migration Generator' do
10
14
  before do
11
15
  load File.expand_path('prepare_testapp.rb', __dir__)
12
16
  end
13
-
14
- let(:charset_alter_table) do
15
- if defined?(Mysql2)
16
- <<~EOS
17
-
18
-
19
- execute "ALTER TABLE `adverts` CHARACTER SET utf8mb4 COLLATE utf8mb4_bin"
20
- EOS
21
- end
22
- end
23
17
  let(:text_limit) do
24
18
  if defined?(Mysql2)
25
19
  ", limit: 4294967295"
@@ -30,21 +24,26 @@ RSpec.describe 'DeclareSchema Migration Generator' do
30
24
  ', charset: "utf8mb4", collation: "utf8mb4_bin"'
31
25
  end
32
26
  end
27
+ let(:create_table_charset_and_collation) do
28
+ if defined?(Mysql2)
29
+ ", options: \"CHARACTER SET utf8mb4 COLLATE utf8mb4_bin\""
30
+ end
31
+ end
33
32
  let(:datetime_precision) do
34
- if defined?(Mysql2) && Rails::VERSION::MAJOR >= 5
33
+ if defined?(Mysql2) && ActiveSupport::VERSION::MAJOR >= 5
35
34
  ', precision: 0'
36
35
  end
37
36
  end
38
37
  let(:table_options) do
39
38
  if defined?(Mysql2)
40
- ", options: \"#{'ENGINE=InnoDB ' if Rails::VERSION::MAJOR == 5}DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\"" +
41
- if Rails::VERSION::MAJOR >= 6
39
+ ", options: \"#{'ENGINE=InnoDB ' if ActiveSupport::VERSION::MAJOR == 5}DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\"" +
40
+ if ActiveSupport::VERSION::MAJOR >= 6
42
41
  ', charset: "utf8mb4", collation: "utf8mb4_bin"'
43
42
  else
44
43
  ''
45
44
  end
46
45
  else
47
- ", id: :integer" unless Rails::VERSION::MAJOR < 5
46
+ ", id: :integer" unless ActiveSupport::VERSION::MAJOR < 5
48
47
  end
49
48
  end
50
49
  let(:lock_version_limit) do
@@ -81,9 +80,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
81
80
  up, _ = Generators::DeclareSchema::Migration::Migrator.run.tap do |migrations|
82
81
  expect(migrations).to(
83
82
  migrate_up(<<~EOS.strip)
84
- create_table :adverts, id: :bigint do |t|
83
+ create_table :adverts, id: :bigint#{create_table_charset_and_collation} do |t|
85
84
  t.string :name, limit: 250, null: true#{charset_and_collation}
86
- end#{charset_alter_table}
85
+ end
87
86
  EOS
88
87
  .and migrate_down("drop_table :adverts")
89
88
  )
@@ -92,7 +91,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
92
91
  ActiveRecord::Migration.class_eval(up)
93
92
  expect(Advert.columns.map(&:name)).to eq(["id", "name"])
94
93
 
95
- if Rails::VERSION::MAJOR < 5
94
+ if ActiveSupport::VERSION::MAJOR < 5
96
95
  # Rails 4 drivers don't always create PK properly. Fix that by dropping and recreating.
97
96
  ActiveRecord::Base.connection.execute("drop table adverts")
98
97
  if defined?(Mysql2)
@@ -119,8 +118,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
119
118
  add_column :adverts, :published_at, :datetime, null: true
120
119
  EOS
121
120
  .and migrate_down(<<~EOS.strip)
122
- remove_column :adverts, :body
123
121
  remove_column :adverts, :published_at
122
+ remove_column :adverts, :body
124
123
  EOS
125
124
  )
126
125
 
@@ -152,8 +151,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
152
151
  remove_column :adverts, :name
153
152
  EOS
154
153
  .and migrate_down(<<~EOS.strip)
155
- remove_column :adverts, :title
156
154
  add_column :adverts, :name, :string, limit: 250, null: true#{charset_and_collation}
155
+ remove_column :adverts, :title
157
156
  EOS
158
157
  )
159
158
 
@@ -370,17 +369,13 @@ RSpec.describe 'DeclareSchema Migration Generator' do
370
369
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
371
370
  migrate_up(<<~EOS.strip)
372
371
  add_column :adverts, :category_id, :integer, limit: 8, null: false
373
-
374
- add_index :adverts, [:category_id], name: 'on_category_id'
375
-
376
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" if defined?(Mysql2)}
372
+ add_index :adverts, [:category_id], name: :on_category_id
373
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id" if defined?(Mysql2)}
377
374
  EOS
378
375
  .and migrate_down(<<~EOS.strip)
376
+ #{"remove_foreign_key :adverts, name: :index_adverts_on_category_id" if defined?(Mysql2)}
377
+ remove_index :adverts, name: :on_category_id
379
378
  remove_column :adverts, :category_id
380
-
381
- remove_index :adverts, name: :on_category_id rescue ActiveRecord::StatementInvalid
382
-
383
- #{"remove_foreign_key(\"adverts\", name: \"on_category_id\")\n" if defined?(Mysql2)}
384
379
  EOS
385
380
  )
386
381
 
@@ -398,11 +393,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
398
393
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
399
394
  migrate_up(<<~EOS.strip)
400
395
  add_column :adverts, :c_id, :integer, limit: 8, null: false
401
-
402
- add_index :adverts, [:c_id], name: 'on_c_id'
403
-
404
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
405
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
396
+ add_index :adverts, [:c_id], name: :on_c_id
397
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
398
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
406
399
  EOS
407
400
  )
408
401
 
@@ -420,9 +413,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
420
413
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
421
414
  migrate_up(<<~EOS.strip)
422
415
  add_column :adverts, :category_id, :integer, limit: 8, null: false
423
-
424
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
425
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
416
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
417
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
426
418
  EOS
427
419
  )
428
420
 
@@ -440,21 +432,19 @@ RSpec.describe 'DeclareSchema Migration Generator' do
440
432
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
441
433
  migrate_up(<<~EOS.strip)
442
434
  add_column :adverts, :category_id, :integer, limit: 8, null: false
443
-
444
- add_index :adverts, [:category_id], name: 'my_index'
445
-
446
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
447
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
435
+ add_index :adverts, [:category_id], name: :my_index
436
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
437
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
448
438
  EOS
449
439
  )
450
440
 
451
441
  Advert.field_specs.delete(:category_id)
452
442
  Advert.index_definitions.delete_if { |spec| spec.fields == ["category_id"] }
453
443
 
454
- ### Timestamps and Optimimistic Locking
444
+ ### Timestamps and Optimistic Locking
455
445
 
456
446
  # `updated_at` and `created_at` can be declared with the shorthand `timestamps`.
457
- # Similarly, `lock_version` can be declared with the "shorthand" `optimimistic_lock`.
447
+ # Similarly, `lock_version` can be declared with the "shorthand" `optimistic_lock`.
458
448
 
459
449
  class Advert < ActiveRecord::Base
460
450
  fields do
@@ -468,17 +458,15 @@ RSpec.describe 'DeclareSchema Migration Generator' do
468
458
  add_column :adverts, :created_at, :datetime, null: true
469
459
  add_column :adverts, :updated_at, :datetime, null: true
470
460
  add_column :adverts, :lock_version, :integer#{lock_version_limit}, null: false, default: 1
471
-
472
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
473
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
461
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
462
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
474
463
  EOS
475
464
  .and migrate_down(<<~EOS.strip)
476
- remove_column :adverts, :created_at
477
- remove_column :adverts, :updated_at
465
+ #{"remove_foreign_key :adverts, name: :index_adverts_on_c_id\n" +
466
+ "remove_foreign_key :adverts, name: :index_adverts_on_category_id" if defined?(Mysql2)}
478
467
  remove_column :adverts, :lock_version
479
-
480
- #{"remove_foreign_key(\"adverts\", name: \"on_category_id\")\n" +
481
- "remove_foreign_key(\"adverts\", name: \"on_c_id\")" if defined?(Mysql2)}
468
+ remove_column :adverts, :updated_at
469
+ remove_column :adverts, :created_at
482
470
  EOS
483
471
  )
484
472
 
@@ -499,11 +487,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
499
487
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
500
488
  migrate_up(<<~EOS.strip)
501
489
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
502
-
503
- add_index :adverts, [:title], name: 'on_title'
504
-
505
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
506
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
490
+ add_index :adverts, [:title], name: :on_title
491
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
492
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
507
493
  EOS
508
494
  )
509
495
 
@@ -520,11 +506,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
520
506
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
521
507
  migrate_up(<<~EOS.strip)
522
508
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
523
-
524
- add_index :adverts, [:title], unique: true, name: 'on_title'
525
-
526
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
527
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
509
+ add_index :adverts, [:title], name: :on_title, unique: true
510
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
511
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
528
512
  EOS
529
513
  )
530
514
 
@@ -541,11 +525,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
541
525
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
542
526
  migrate_up(<<~EOS.strip)
543
527
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
544
-
545
- add_index :adverts, [:title], name: 'my_index'
546
-
547
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
548
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
528
+ add_index :adverts, [:title], name: :my_index
529
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
530
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
549
531
  EOS
550
532
  )
551
533
 
@@ -560,11 +542,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
560
542
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
561
543
  migrate_up(<<~EOS.strip)
562
544
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
563
-
564
- add_index :adverts, [:title], name: 'on_title'
565
-
566
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
567
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
545
+ add_index :adverts, [:title], name: :on_title
546
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
547
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
568
548
  EOS
569
549
  )
570
550
 
@@ -579,11 +559,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
579
559
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
580
560
  migrate_up(<<~EOS.strip)
581
561
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
582
-
583
- add_index :adverts, [:title], unique: true, name: 'my_index'
584
-
585
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
586
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
562
+ add_index :adverts, [:title], name: :my_index, unique: true
563
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
564
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
587
565
  EOS
588
566
  )
589
567
 
@@ -598,11 +576,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
598
576
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
599
577
  migrate_up(<<~EOS.strip)
600
578
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
601
-
602
- add_index :adverts, [:title, :category_id], name: 'on_title_and_category_id'
603
-
604
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
605
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
579
+ add_index :adverts, [:title, :category_id], name: :on_title_and_category_id
580
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
581
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
606
582
  EOS
607
583
  )
608
584
 
@@ -614,7 +590,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
614
590
 
615
591
  ### Rename a table
616
592
 
617
- # The migration generator respects the `set_table_name` declaration, although as before, we need to explicitly tell the generator that we want a rename rather than a create and a drop.
593
+ # The migration generator respects the `set_table_name` declaration, although as before,
594
+ # we need to explicitly tell the generator that we want a rename rather than a create and a drop.
618
595
 
619
596
  class Advert < ActiveRecord::Base
620
597
  self.table_name = "ads"
@@ -630,31 +607,21 @@ RSpec.describe 'DeclareSchema Migration Generator' do
630
607
  expect(Generators::DeclareSchema::Migration::Migrator.run("adverts" => "ads")).to(
631
608
  migrate_up(<<~EOS.strip)
632
609
  rename_table :adverts, :ads
633
-
634
610
  add_column :ads, :title, :string, limit: 250, null: true#{charset_and_collation}
635
611
  add_column :ads, :body, :text#{', limit: 4294967295' if defined?(Mysql2)}, null: true#{charset_and_collation}
636
-
637
- #{if defined?(SQLite3)
638
- "add_index :ads, [:id], unique: true, name: 'PRIMARY'\n"
639
- elsif defined?(Mysql2)
640
- "execute \"ALTER TABLE ads DROP PRIMARY KEY, ADD PRIMARY KEY (id)\"\n\n" +
641
- "add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
642
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")"
612
+ #{if defined?(Mysql2)
613
+ "add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
614
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id"
643
615
  end}
644
616
  EOS
645
617
  .and migrate_down(<<~EOS.strip)
646
- remove_column :ads, :title
618
+ #{if defined?(Mysql2)
619
+ "remove_foreign_key :adverts, name: :index_adverts_on_c_id\n" +
620
+ "remove_foreign_key :adverts, name: :index_adverts_on_category_id"
621
+ end}
647
622
  remove_column :ads, :body
648
-
623
+ remove_column :ads, :title
649
624
  rename_table :ads, :adverts
650
-
651
- #{if defined?(SQLite3)
652
- "add_index :adverts, [:id], unique: true, name: 'PRIMARY'\n"
653
- elsif defined?(Mysql2)
654
- "execute \"ALTER TABLE adverts DROP PRIMARY KEY, ADD PRIMARY KEY (id)\"\n\n" +
655
- "remove_foreign_key(\"adverts\", name: \"on_category_id\")\n" +
656
- "remove_foreign_key(\"adverts\", name: \"on_c_id\")"
657
- end}
658
625
  EOS
659
626
  )
660
627
 
@@ -684,29 +651,15 @@ RSpec.describe 'DeclareSchema Migration Generator' do
684
651
  expect(Generators::DeclareSchema::Migration::Migrator.run("adverts" => "advertisements")).to(
685
652
  migrate_up(<<~EOS.strip)
686
653
  rename_table :adverts, :advertisements
687
-
688
654
  add_column :advertisements, :title, :string, limit: 250, null: true#{charset_and_collation}
689
655
  add_column :advertisements, :body, :text#{', limit: 4294967295' if defined?(Mysql2)}, null: true#{charset_and_collation}
690
656
  remove_column :advertisements, :name
691
-
692
- #{if defined?(SQLite3)
693
- "add_index :advertisements, [:id], unique: true, name: 'PRIMARY'"
694
- elsif defined?(Mysql2)
695
- "execute \"ALTER TABLE advertisements DROP PRIMARY KEY, ADD PRIMARY KEY (id)\""
696
- end}
697
657
  EOS
698
658
  .and migrate_down(<<~EOS.strip)
699
- remove_column :advertisements, :title
659
+ add_column :advertisements, :name, :string, limit: 250, null: true#{charset_and_collation}
700
660
  remove_column :advertisements, :body
701
- add_column :adverts, :name, :string, limit: 250, null: true#{charset_and_collation}
702
-
661
+ remove_column :advertisements, :title
703
662
  rename_table :advertisements, :adverts
704
-
705
- #{if defined?(SQLite3)
706
- "add_index :adverts, [:id], unique: true, name: 'PRIMARY'"
707
- elsif defined?(Mysql2)
708
- "execute \"ALTER TABLE adverts DROP PRIMARY KEY, ADD PRIMARY KEY (id)\""
709
- end}
710
663
  EOS
711
664
  )
712
665
 
@@ -753,13 +706,11 @@ RSpec.describe 'DeclareSchema Migration Generator' do
753
706
  expect(migrations).to(
754
707
  migrate_up(<<~EOS.strip)
755
708
  add_column :adverts, :type, :string, limit: 250, null: true#{charset_and_collation}
756
-
757
- add_index :adverts, [:type], name: 'on_type'
709
+ add_index :adverts, [:type], name: :on_type
758
710
  EOS
759
711
  .and migrate_down(<<~EOS.strip)
760
712
  remove_column :adverts, :type
761
-
762
- remove_index :adverts, name: :on_type rescue ActiveRecord::StatementInvalid
713
+ remove_index :adverts, name: :on_type
763
714
  EOS
764
715
  )
765
716
  end
@@ -802,8 +753,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
802
753
  change_column :adverts, :name, :string, limit: 250, null: true, default: "No Name"#{charset_and_collation}
803
754
  EOS
804
755
  .and migrate_down(<<~EOS.strip)
756
+ change_column :adverts, :name, :string, limit: 250, null: true, default: "Untitled"#{charset_and_collation}
805
757
  rename_column :adverts, :name, :title
806
- change_column :adverts, :title, :string, limit: 250, null: true, default: "Untitled"#{charset_and_collation}
807
758
  EOS
808
759
  )
809
760
 
@@ -821,15 +772,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
821
772
  expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: :ads)).to(
822
773
  migrate_up(<<~EOS.strip)
823
774
  rename_table :adverts, :ads
824
-
825
775
  add_column :ads, :created_at, :datetime, null: false
826
776
  change_column :ads, :title, :string, limit: 250, null: false, default: \"Untitled\"#{charset_and_collation}
827
-
828
- #{if defined?(SQLite3)
829
- "add_index :ads, [:id], unique: true, name: 'PRIMARY'"
830
- elsif defined?(Mysql2)
831
- 'execute "ALTER TABLE ads DROP PRIMARY KEY, ADD PRIMARY KEY (id)"'
832
- end}
833
777
  EOS
834
778
  )
835
779
 
@@ -856,12 +800,6 @@ RSpec.describe 'DeclareSchema Migration Generator' do
856
800
  expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { id: :advert_id })).to(
857
801
  migrate_up(<<~EOS.strip)
858
802
  rename_column :adverts, :id, :advert_id
859
-
860
- #{if defined?(SQLite3)
861
- "add_index :adverts, [:advert_id], unique: true, name: 'PRIMARY'"
862
- elsif defined?(Mysql2)
863
- 'execute "ALTER TABLE adverts DROP PRIMARY KEY, ADD PRIMARY KEY (advert_id)"'
864
- end}
865
803
  EOS
866
804
  )
867
805
 
@@ -902,6 +840,54 @@ RSpec.describe 'DeclareSchema Migration Generator' do
902
840
  expect(Ad.field_specs['company'].options[:validates].inspect).to eq("{:presence=>true, :uniqueness=>{:case_sensitive=>false}}")
903
841
  end
904
842
 
843
+ context 'models with the same parent foreign key relation' do
844
+ before do
845
+ class Category < ActiveRecord::Base
846
+ fields do
847
+ name :string, limit: 250, null: true
848
+ end
849
+ end
850
+ class Advertiser < ActiveRecord::Base
851
+ fields do
852
+ name :string, limit: 250, null: true
853
+ end
854
+ belongs_to :category, limit: 8
855
+ end
856
+ class Affiliate < ActiveRecord::Base
857
+ fields do
858
+ name :string, limit: 250, null: true
859
+ end
860
+ belongs_to :category, limit: 8
861
+ end
862
+ end
863
+
864
+ it 'will genereate unique constraint names' do
865
+ expect(Generators::DeclareSchema::Migration::Migrator.run).to(
866
+ migrate_up(<<~EOS.strip)
867
+ create_table :categories, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
868
+ t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
869
+ end
870
+ create_table :advertisers, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
871
+ t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
872
+ t.integer :category_id, limit: 8, null: false
873
+ end
874
+ create_table :affiliates, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
875
+ t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
876
+ t.integer :category_id, limit: 8, null: false
877
+ end
878
+ add_index :advertisers, [:category_id], name: :on_category_id
879
+ add_index :affiliates, [:category_id], name: :on_category_id
880
+ add_foreign_key :advertisers, :categories, column: :category_id, name: :index_advertisers_on_category_id
881
+ add_foreign_key :affiliates, :categories, column: :category_id, name: :index_affiliates_on_category_id
882
+ EOS
883
+ )
884
+ migrate
885
+
886
+ nuke_model_class(Advertiser)
887
+ nuke_model_class(Affiliate)
888
+ end
889
+ end if !defined?(SQLite3) && ActiveRecord::VERSION::MAJOR >= 5
890
+
905
891
  describe 'serialize' do
906
892
  before do
907
893
  class Ad < ActiveRecord::Base
@@ -1086,8 +1072,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1086
1072
  end
1087
1073
  end
1088
1074
 
1089
- context "for Rails #{Rails::VERSION::MAJOR}" do
1090
- if Rails::VERSION::MAJOR >= 5
1075
+ context "for Rails #{ActiveSupport::VERSION::MAJOR}" do
1076
+ if ActiveSupport::VERSION::MAJOR >= 5
1091
1077
  let(:optional_true) { { optional: true } }
1092
1078
  let(:optional_false) { { optional: false } }
1093
1079
  else
@@ -1193,13 +1179,13 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1193
1179
  migration_content = File.read(migrations.first)
1194
1180
  first_line = migration_content.split("\n").first
1195
1181
  base_class = first_line.split(' < ').last
1196
- expect(base_class).to eq("(Rails::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)")
1182
+ expect(base_class).to eq("(ActiveSupport::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)")
1197
1183
  end
1198
1184
  end
1199
1185
 
1200
1186
  context 'Does not generate migrations' do
1201
1187
  it 'for aliased fields bigint -> integer limit 8' do
1202
- if Rails::VERSION::MAJOR >= 5 || !ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
1188
+ if ActiveSupport::VERSION::MAJOR >= 5 || !ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
1203
1189
  class Advert < active_record_base_class.constantize
1204
1190
  fields do
1205
1191
  price :bigint
@@ -1211,7 +1197,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1211
1197
  migrations = Dir.glob('db/migrate/*declare_schema_migration*.rb')
1212
1198
  expect(migrations.size).to eq(1), migrations.inspect
1213
1199
 
1214
- if defined?(Mysql2) && Rails::VERSION::MAJOR < 5
1200
+ if defined?(Mysql2) && ActiveSupport::VERSION::MAJOR < 5
1215
1201
  ActiveRecord::Base.connection.execute("ALTER TABLE adverts ADD PRIMARY KEY (id)")
1216
1202
  end
1217
1203
 
@@ -1252,19 +1238,19 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1252
1238
 
1253
1239
  up, _ = Generators::DeclareSchema::Migration::Migrator.run.tap do |migrations|
1254
1240
  expect(migrations).to(
1255
- migrate_up(<<~EOS.strip)
1256
- create_table :adverts, id: :bigint do |t|
1241
+ migrate_up(<<~EOS.strip)
1242
+ create_table :adverts, id: :bigint#{create_table_charset_and_collation} do |t|
1257
1243
  t.string :name, limit: 250, null: true#{charset_and_collation}
1258
- end#{charset_alter_table}
1259
- EOS
1260
- .and migrate_down("drop_table :adverts")
1244
+ end
1245
+ EOS
1246
+ .and migrate_down("drop_table :adverts")
1261
1247
  )
1262
1248
  end
1263
1249
 
1264
1250
  ActiveRecord::Migration.class_eval(up)
1265
1251
  expect(Advert.columns.map(&:name)).to eq(["id", "name"])
1266
1252
 
1267
- if Rails::VERSION::MAJOR < 5
1253
+ if ActiveSupport::VERSION::MAJOR < 5
1268
1254
  # Rails 4 drivers don't always create PK properly. Fix that by dropping and recreating.
1269
1255
  ActiveRecord::Base.connection.execute("drop table adverts")
1270
1256
  if defined?(Mysql2)
@@ -1286,14 +1272,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1286
1272
  Advert.reset_column_information
1287
1273
 
1288
1274
  expect(migrate).to(
1289
- migrate_up(<<~EOS.strip)
1275
+ migrate_up(<<~EOS.strip)
1290
1276
  add_column :adverts, :body, :text#{text_limit}, null: true#{charset_and_collation}
1291
1277
  add_column :adverts, :published_at, :datetime, null: true
1292
- EOS
1293
- .and migrate_down(<<~EOS.strip)
1294
- remove_column :adverts, :body
1278
+ EOS
1279
+ .and migrate_down(<<~EOS.strip)
1295
1280
  remove_column :adverts, :published_at
1296
- EOS
1281
+ remove_column :adverts, :body
1282
+ EOS
1297
1283
  )
1298
1284
 
1299
1285
  Advert.field_specs.clear # not normally needed
@@ -1319,14 +1305,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1319
1305
  end
1320
1306
 
1321
1307
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1322
- migrate_up(<<~EOS.strip)
1308
+ migrate_up(<<~EOS.strip)
1323
1309
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
1324
1310
  remove_column :adverts, :name
1325
- EOS
1326
- .and migrate_down(<<~EOS.strip)
1327
- remove_column :adverts, :title
1311
+ EOS
1312
+ .and migrate_down(<<~EOS.strip)
1328
1313
  add_column :adverts, :name, :string, limit: 250, null: true#{charset_and_collation}
1329
- EOS
1314
+ remove_column :adverts, :title
1315
+ EOS
1330
1316
  )
1331
1317
 
1332
1318
  expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { name: :title })).to(
@@ -1540,20 +1526,16 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1540
1526
  end
1541
1527
 
1542
1528
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1543
- migrate_up(<<~EOS.strip)
1529
+ migrate_up(<<~EOS.strip)
1544
1530
  add_column :adverts, :category_id, :integer, limit: 8, null: false
1545
-
1546
- add_index :adverts, [:category_id], name: 'on_category_id'
1547
-
1548
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" if defined?(Mysql2)}
1549
- EOS
1550
- .and migrate_down(<<~EOS.strip)
1531
+ add_index :adverts, [:category_id], name: :on_category_id
1532
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" if defined?(Mysql2)}
1533
+ EOS
1534
+ .and migrate_down(<<~EOS.strip)
1535
+ #{"remove_foreign_key :adverts, name: :index_adverts_on_category_id" if defined?(Mysql2)}
1536
+ remove_index :adverts, name: :on_category_id
1551
1537
  remove_column :adverts, :category_id
1552
-
1553
- remove_index :adverts, name: :on_category_id rescue ActiveRecord::StatementInvalid
1554
-
1555
- #{"remove_foreign_key(\"adverts\", name: \"on_category_id\")\n" if defined?(Mysql2)}
1556
- EOS
1538
+ EOS
1557
1539
  )
1558
1540
 
1559
1541
  Advert.field_specs.delete(:category_id)
@@ -1568,14 +1550,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1568
1550
  end
1569
1551
 
1570
1552
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1571
- migrate_up(<<~EOS.strip)
1553
+ migrate_up(<<~EOS.strip)
1572
1554
  add_column :adverts, :c_id, :integer, limit: 8, null: false
1573
-
1574
- add_index :adverts, [:c_id], name: 'on_c_id'
1575
-
1576
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1577
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
1578
- EOS
1555
+ add_index :adverts, [:c_id], name: :on_c_id
1556
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1557
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
1558
+ EOS
1579
1559
  )
1580
1560
 
1581
1561
  Advert.field_specs.delete(:c_id)
@@ -1590,12 +1570,11 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1590
1570
  end
1591
1571
 
1592
1572
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1593
- migrate_up(<<~EOS.strip)
1573
+ migrate_up(<<~EOS.strip)
1594
1574
  add_column :adverts, :category_id, :integer, limit: 8, null: false
1595
-
1596
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1597
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
1598
- EOS
1575
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1576
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
1577
+ EOS
1599
1578
  )
1600
1579
 
1601
1580
  Advert.field_specs.delete(:category_id)
@@ -1610,14 +1589,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1610
1589
  end
1611
1590
 
1612
1591
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1613
- migrate_up(<<~EOS.strip)
1592
+ migrate_up(<<~EOS.strip)
1614
1593
  add_column :adverts, :category_id, :integer, limit: 8, null: false
1615
-
1616
- add_index :adverts, [:category_id], name: 'my_index'
1617
-
1618
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1619
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
1620
- EOS
1594
+ add_index :adverts, [:category_id], name: :my_index
1595
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1596
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
1597
+ EOS
1621
1598
  )
1622
1599
 
1623
1600
  Advert.field_specs.delete(:category_id)
@@ -1636,22 +1613,20 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1636
1613
  end
1637
1614
 
1638
1615
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1639
- migrate_up(<<~EOS.strip)
1616
+ migrate_up(<<~EOS.strip)
1640
1617
  add_column :adverts, :created_at, :datetime, null: true
1641
1618
  add_column :adverts, :updated_at, :datetime, null: true
1642
1619
  add_column :adverts, :lock_version, :integer#{lock_version_limit}, null: false, default: 1
1643
-
1644
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1645
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
1646
- EOS
1647
- .and migrate_down(<<~EOS.strip)
1648
- remove_column :adverts, :created_at
1649
- remove_column :adverts, :updated_at
1620
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1621
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
1622
+ EOS
1623
+ .and migrate_down(<<~EOS.strip)
1624
+ #{"remove_foreign_key :adverts, name: :index_adverts_on_c_id\n" +
1625
+ "remove_foreign_key :adverts, name: :index_adverts_on_category_id" if defined?(Mysql2)}
1650
1626
  remove_column :adverts, :lock_version
1651
-
1652
- #{"remove_foreign_key(\"adverts\", name: \"on_category_id\")\n" +
1653
- "remove_foreign_key(\"adverts\", name: \"on_c_id\")" if defined?(Mysql2)}
1654
- EOS
1627
+ remove_column :adverts, :updated_at
1628
+ remove_column :adverts, :created_at
1629
+ EOS
1655
1630
  )
1656
1631
 
1657
1632
  Advert.field_specs.delete(:updated_at)
@@ -1669,14 +1644,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1669
1644
  end
1670
1645
 
1671
1646
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1672
- migrate_up(<<~EOS.strip)
1647
+ migrate_up(<<~EOS.strip)
1673
1648
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
1674
-
1675
- add_index :adverts, [:title], name: 'on_title'
1676
-
1677
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1678
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
1679
- EOS
1649
+ add_index :adverts, [:title], name: :on_title
1650
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1651
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
1652
+ EOS
1680
1653
  )
1681
1654
 
1682
1655
  Advert.index_definitions.delete_if { |spec| spec.fields==["title"] }
@@ -1690,14 +1663,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1690
1663
  end
1691
1664
 
1692
1665
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1693
- migrate_up(<<~EOS.strip)
1666
+ migrate_up(<<~EOS.strip)
1694
1667
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
1695
-
1696
- add_index :adverts, [:title], unique: true, name: 'on_title'
1697
-
1698
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1699
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
1700
- EOS
1668
+ add_index :adverts, [:title], name: :on_title, unique: true
1669
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1670
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
1671
+ EOS
1701
1672
  )
1702
1673
 
1703
1674
  Advert.index_definitions.delete_if { |spec| spec.fields == ["title"] }
@@ -1711,14 +1682,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1711
1682
  end
1712
1683
 
1713
1684
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1714
- migrate_up(<<~EOS.strip)
1685
+ migrate_up(<<~EOS.strip)
1715
1686
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
1716
-
1717
- add_index :adverts, [:title], name: 'my_index'
1718
-
1719
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1720
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
1721
- EOS
1687
+ add_index :adverts, [:title], name: :my_index
1688
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1689
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
1690
+ EOS
1722
1691
  )
1723
1692
 
1724
1693
  Advert.index_definitions.delete_if { |spec| spec.fields==["title"] }
@@ -1730,14 +1699,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1730
1699
  end
1731
1700
 
1732
1701
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1733
- migrate_up(<<~EOS.strip)
1702
+ migrate_up(<<~EOS.strip)
1734
1703
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
1735
-
1736
- add_index :adverts, [:title], name: 'on_title'
1737
-
1738
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1739
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
1740
- EOS
1704
+ add_index :adverts, [:title], name: :on_title
1705
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1706
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
1707
+ EOS
1741
1708
  )
1742
1709
 
1743
1710
  Advert.index_definitions.delete_if { |spec| spec.fields == ["title"] }
@@ -1749,14 +1716,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1749
1716
  end
1750
1717
 
1751
1718
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1752
- migrate_up(<<~EOS.strip)
1719
+ migrate_up(<<~EOS.strip)
1753
1720
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
1754
-
1755
- add_index :adverts, [:title], unique: true, name: 'my_index'
1756
-
1757
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1758
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
1759
- EOS
1721
+ add_index :adverts, [:title], name: :my_index, unique: true
1722
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1723
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
1724
+ EOS
1760
1725
  )
1761
1726
 
1762
1727
  Advert.index_definitions.delete_if { |spec| spec.fields == ["title"] }
@@ -1768,14 +1733,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1768
1733
  end
1769
1734
 
1770
1735
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1771
- migrate_up(<<~EOS.strip)
1736
+ migrate_up(<<~EOS.strip)
1772
1737
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
1773
-
1774
- add_index :adverts, [:title, :category_id], name: 'on_title_and_category_id'
1775
-
1776
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1777
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
1778
- EOS
1738
+ add_index :adverts, [:title, :category_id], name: :on_title_and_category_id
1739
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1740
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
1741
+ EOS
1779
1742
  )
1780
1743
 
1781
1744
  Advert.index_definitions.delete_if { |spec| spec.fields==["title", "category_id"] }
@@ -1800,34 +1763,24 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1800
1763
  Advert.reset_column_information
1801
1764
 
1802
1765
  expect(Generators::DeclareSchema::Migration::Migrator.run("adverts" => "ads")).to(
1803
- migrate_up(<<~EOS.strip)
1766
+ migrate_up(<<~EOS.strip)
1804
1767
  rename_table :adverts, :ads
1805
-
1806
1768
  add_column :ads, :title, :string, limit: 250, null: true#{charset_and_collation}
1807
1769
  add_column :ads, :body, :text#{', limit: 4294967295' if defined?(Mysql2)}, null: true#{charset_and_collation}
1808
-
1809
- #{if defined?(SQLite3)
1810
- "add_index :ads, [:id], unique: true, name: 'PRIMARY'\n"
1811
- elsif defined?(Mysql2)
1812
- "execute \"ALTER TABLE ads DROP PRIMARY KEY, ADD PRIMARY KEY (id)\"\n\n" +
1813
- "add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
1814
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")"
1770
+ #{if defined?(Mysql2)
1771
+ "add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
1772
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id"
1815
1773
  end}
1816
1774
  EOS
1817
- .and migrate_down(<<~EOS.strip)
1818
- remove_column :ads, :title
1819
- remove_column :ads, :body
1820
-
1821
- rename_table :ads, :adverts
1822
-
1823
- #{if defined?(SQLite3)
1824
- "add_index :adverts, [:id], unique: true, name: 'PRIMARY'\n"
1825
- elsif defined?(Mysql2)
1826
- "execute \"ALTER TABLE adverts DROP PRIMARY KEY, ADD PRIMARY KEY (id)\"\n\n" +
1827
- "remove_foreign_key(\"adverts\", name: \"on_category_id\")\n" +
1828
- "remove_foreign_key(\"adverts\", name: \"on_c_id\")"
1829
- end}
1830
- EOS
1775
+ .and migrate_down(<<~EOS.strip)
1776
+ #{if defined?(Mysql2)
1777
+ "remove_foreign_key :adverts, name: :index_adverts_on_c_id\n" +
1778
+ "remove_foreign_key :adverts, name: :index_adverts_on_category_id"
1779
+ end}
1780
+ remove_column :ads, :body
1781
+ remove_column :ads, :title
1782
+ rename_table :ads, :adverts
1783
+ EOS
1831
1784
  )
1832
1785
 
1833
1786
  # Set the table name back to what it should be and confirm we're in sync:
@@ -1854,32 +1807,18 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1854
1807
  end
1855
1808
 
1856
1809
  expect(Generators::DeclareSchema::Migration::Migrator.run("adverts" => "advertisements")).to(
1857
- migrate_up(<<~EOS.strip)
1810
+ migrate_up(<<~EOS.strip)
1858
1811
  rename_table :adverts, :advertisements
1859
-
1860
1812
  add_column :advertisements, :title, :string, limit: 250, null: true#{charset_and_collation}
1861
1813
  add_column :advertisements, :body, :text#{', limit: 4294967295' if defined?(Mysql2)}, null: true#{charset_and_collation}
1862
1814
  remove_column :advertisements, :name
1863
-
1864
- #{if defined?(SQLite3)
1865
- "add_index :advertisements, [:id], unique: true, name: 'PRIMARY'"
1866
- elsif defined?(Mysql2)
1867
- "execute \"ALTER TABLE advertisements DROP PRIMARY KEY, ADD PRIMARY KEY (id)\""
1868
- end}
1869
- EOS
1870
- .and migrate_down(<<~EOS.strip)
1871
- remove_column :advertisements, :title
1815
+ EOS
1816
+ .and migrate_down(<<~EOS.strip)
1817
+ add_column :advertisements, :name, :string, limit: 250, null: true#{charset_and_collation}
1872
1818
  remove_column :advertisements, :body
1873
- add_column :adverts, :name, :string, limit: 250, null: true#{charset_and_collation}
1874
-
1819
+ remove_column :advertisements, :title
1875
1820
  rename_table :advertisements, :adverts
1876
-
1877
- #{if defined?(SQLite3)
1878
- "add_index :adverts, [:id], unique: true, name: 'PRIMARY'"
1879
- elsif defined?(Mysql2)
1880
- "execute \"ALTER TABLE adverts DROP PRIMARY KEY, ADD PRIMARY KEY (id)\""
1881
- end}
1882
- EOS
1821
+ EOS
1883
1822
  )
1884
1823
 
1885
1824
  ### Drop a table
@@ -1891,14 +1830,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1891
1830
  # Dropping tables is where the automatic down-migration really comes in handy:
1892
1831
 
1893
1832
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
1894
- migrate_up(<<~EOS.strip)
1833
+ migrate_up(<<~EOS.strip)
1895
1834
  drop_table :adverts
1896
- EOS
1897
- .and migrate_down(<<~EOS.strip)
1835
+ EOS
1836
+ .and migrate_down(<<~EOS.strip)
1898
1837
  create_table "adverts"#{table_options}, force: :cascade do |t|
1899
1838
  t.string "name", limit: 250#{charset_and_collation}
1900
1839
  end
1901
- EOS
1840
+ EOS
1902
1841
  )
1903
1842
 
1904
1843
  ## STI
@@ -1923,16 +1862,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1923
1862
 
1924
1863
  up, _ = Generators::DeclareSchema::Migration::Migrator.run do |migrations|
1925
1864
  expect(migrations).to(
1926
- migrate_up(<<~EOS.strip)
1865
+ migrate_up(<<~EOS.strip)
1927
1866
  add_column :adverts, :type, :string, limit: 250, null: true#{charset_and_collation}
1928
-
1929
- add_index :adverts, [:type], name: 'on_type'
1930
- EOS
1931
- .and migrate_down(<<~EOS.strip)
1867
+ add_index :adverts, [:type], name: :on_type
1868
+ EOS
1869
+ .and migrate_down(<<~EOS.strip)
1870
+ remove_index :adverts, name: :on_type
1932
1871
  remove_column :adverts, :type
1933
-
1934
- remove_index :adverts, name: :on_type rescue ActiveRecord::StatementInvalid
1935
- EOS
1872
+ EOS
1936
1873
  )
1937
1874
  end
1938
1875
 
@@ -1969,14 +1906,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1969
1906
  end
1970
1907
 
1971
1908
  expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { title: :name })).to(
1972
- migrate_up(<<~EOS.strip)
1909
+ migrate_up(<<~EOS.strip)
1973
1910
  rename_column :adverts, :title, :name
1974
1911
  change_column :adverts, :name, :string, limit: 250, null: true, default: "No Name"#{charset_and_collation}
1975
- EOS
1976
- .and migrate_down(<<~EOS.strip)
1912
+ EOS
1913
+ .and migrate_down(<<~EOS.strip)
1914
+ change_column :adverts, :name, :string, limit: 250, null: true, default: "Untitled"#{charset_and_collation}
1977
1915
  rename_column :adverts, :name, :title
1978
- change_column :adverts, :title, :string, limit: 250, null: true, default: "Untitled"#{charset_and_collation}
1979
- EOS
1916
+ EOS
1980
1917
  )
1981
1918
 
1982
1919
  ### Rename a table and add a column
@@ -1991,18 +1928,11 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1991
1928
  end
1992
1929
 
1993
1930
  expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: :ads)).to(
1994
- migrate_up(<<~EOS.strip)
1931
+ migrate_up(<<~EOS.strip)
1995
1932
  rename_table :adverts, :ads
1996
-
1997
1933
  add_column :ads, :created_at, :datetime, null: false
1998
1934
  change_column :ads, :title, :string, limit: 250, null: false, default: \"Untitled\"#{charset_and_collation}
1999
-
2000
- #{if defined?(SQLite3)
2001
- "add_index :ads, [:id], unique: true, name: 'PRIMARY'"
2002
- elsif defined?(Mysql2)
2003
- 'execute "ALTER TABLE ads DROP PRIMARY KEY, ADD PRIMARY KEY (id)"'
2004
- end}
2005
- EOS
1935
+ EOS
2006
1936
  )
2007
1937
 
2008
1938
  class Advert < ActiveRecord::Base
@@ -2026,15 +1956,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
2026
1956
  end
2027
1957
 
2028
1958
  expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { id: :advert_id })).to(
2029
- migrate_up(<<~EOS.strip)
1959
+ migrate_up(<<~EOS.strip)
2030
1960
  rename_column :adverts, :id, :advert_id
2031
-
2032
- #{if defined?(SQLite3)
2033
- "add_index :adverts, [:advert_id], unique: true, name: 'PRIMARY'"
2034
- elsif defined?(Mysql2)
2035
- 'execute "ALTER TABLE adverts DROP PRIMARY KEY, ADD PRIMARY KEY (advert_id)"'
2036
- end}
2037
- EOS
1961
+ EOS
2038
1962
  )
2039
1963
 
2040
1964
  nuke_model_class(Advert)
@@ -2074,6 +1998,54 @@ RSpec.describe 'DeclareSchema Migration Generator' do
2074
1998
  expect(Ad.field_specs['company'].options[:validates].inspect).to eq("{:presence=>true, :uniqueness=>{:case_sensitive=>false}}")
2075
1999
  end
2076
2000
 
2001
+ context 'models with the same parent foreign key relation' do
2002
+ before do
2003
+ class Category < ActiveRecord::Base
2004
+ fields do
2005
+ name :string, limit: 250, null: true
2006
+ end
2007
+ end
2008
+ class Advertiser < ActiveRecord::Base
2009
+ fields do
2010
+ name :string, limit: 250, null: true
2011
+ end
2012
+ belongs_to :category, limit: 8
2013
+ end
2014
+ class Affiliate < ActiveRecord::Base
2015
+ fields do
2016
+ name :string, limit: 250, null: true
2017
+ end
2018
+ belongs_to :category, limit: 8
2019
+ end
2020
+ end
2021
+
2022
+ it 'will genereate unique constraint names' do
2023
+ expect(Generators::DeclareSchema::Migration::Migrator.run).to(
2024
+ migrate_up(<<~EOS.strip)
2025
+ create_table :categories, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
2026
+ t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
2027
+ end
2028
+ create_table :advertisers, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
2029
+ t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
2030
+ t.integer :category_id, limit: 8, null: false
2031
+ end
2032
+ create_table :affiliates, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
2033
+ t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
2034
+ t.integer :category_id, limit: 8, null: false
2035
+ end
2036
+ add_index :advertisers, [:category_id], name: :on_category_id
2037
+ add_index :affiliates, [:category_id], name: :on_category_id
2038
+ add_foreign_key :advertisers, :categories, column: :category_id, name: :index_advertisers_on_category_id
2039
+ add_foreign_key :affiliates, :categories, column: :category_id, name: :index_affiliates_on_category_id
2040
+ EOS
2041
+ )
2042
+ migrate
2043
+
2044
+ nuke_model_class(Advertiser)
2045
+ nuke_model_class(Affiliate)
2046
+ end
2047
+ end if !defined?(SQLite3) && ActiveRecord::VERSION::MAJOR >= 5
2048
+
2077
2049
  describe 'serialize' do
2078
2050
  before do
2079
2051
  class Ad < ActiveRecord::Base
@@ -2258,8 +2230,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
2258
2230
  end
2259
2231
  end
2260
2232
 
2261
- context "for Rails #{Rails::VERSION::MAJOR}" do
2262
- if Rails::VERSION::MAJOR >= 5
2233
+ context "for Rails #{ActiveSupport::VERSION::MAJOR}" do
2234
+ if ActiveSupport::VERSION::MAJOR >= 5
2263
2235
  let(:optional_true) { { optional: true } }
2264
2236
  let(:optional_false) { { optional: false } }
2265
2237
  else
@@ -2269,80 +2241,202 @@ RSpec.describe 'DeclareSchema Migration Generator' do
2269
2241
  let(:optional_flag) { { false => optional_false, true => optional_true } }
2270
2242
 
2271
2243
  describe 'belongs_to' do
2272
- before do
2273
- unless defined?(AdCategory)
2274
- class AdCategory < ActiveRecord::Base
2275
- declare_schema { }
2244
+ context 'with AdCategory and Advert in DB' do
2245
+ before do
2246
+ unless defined?(AdCategory)
2247
+ class AdCategory < ActiveRecord::Base
2248
+ declare_schema { }
2249
+ end
2276
2250
  end
2277
- end
2278
2251
 
2279
- class Advert < ActiveRecord::Base
2280
- declare_schema do
2281
- string :name, limit: 250, null: true
2282
- integer :category_id, limit: 8
2283
- integer :nullable_category_id, limit: 8, null: true
2252
+ class Advert < ActiveRecord::Base
2253
+ declare_schema do
2254
+ string :name, limit: 250, null: true
2255
+ integer :category_id, limit: 8
2256
+ integer :nullable_category_id, limit: 8, null: true
2257
+ end
2284
2258
  end
2259
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
2260
+ ActiveRecord::Migration.class_eval(up)
2285
2261
  end
2286
- up = Generators::DeclareSchema::Migration::Migrator.run.first
2287
- ActiveRecord::Migration.class_eval(up)
2288
- end
2289
2262
 
2290
- it 'passes through optional: when given' do
2291
- class AdvertBelongsTo < ActiveRecord::Base
2292
- self.table_name = 'adverts'
2293
- declare_schema { }
2294
- reset_column_information
2295
- belongs_to :ad_category, optional: true
2296
- end
2297
- expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_true)
2298
- end
2299
-
2300
- describe 'contradictory settings' do # contradictory settings are ok--for example, during migration
2301
- it 'passes through optional: true, null: false' do
2263
+ it 'passes through optional: when given' do
2302
2264
  class AdvertBelongsTo < ActiveRecord::Base
2303
2265
  self.table_name = 'adverts'
2304
2266
  declare_schema { }
2305
2267
  reset_column_information
2306
- belongs_to :ad_category, optional: true, null: false
2268
+ belongs_to :ad_category, optional: true
2307
2269
  end
2308
2270
  expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_true)
2309
- expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(false)
2310
2271
  end
2311
2272
 
2312
- it 'passes through optional: false, null: true' do
2313
- class AdvertBelongsTo < ActiveRecord::Base
2314
- self.table_name = 'adverts'
2315
- declare_schema { }
2316
- reset_column_information
2317
- belongs_to :ad_category, optional: false, null: true
2273
+ describe 'contradictory settings' do # contradictory settings are ok--for example, during migration
2274
+ it 'passes through optional: true, null: false' do
2275
+ class AdvertBelongsTo < ActiveRecord::Base
2276
+ self.table_name = 'adverts'
2277
+ declare_schema { }
2278
+ reset_column_information
2279
+ belongs_to :ad_category, optional: true, null: false
2280
+ end
2281
+ expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_true)
2282
+ expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(false)
2318
2283
  end
2319
- expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_false)
2320
- expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(true)
2284
+
2285
+ it 'passes through optional: false, null: true' do
2286
+ class AdvertBelongsTo < ActiveRecord::Base
2287
+ self.table_name = 'adverts'
2288
+ declare_schema { }
2289
+ reset_column_information
2290
+ belongs_to :ad_category, optional: false, null: true
2291
+ end
2292
+ expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_false)
2293
+ expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(true)
2294
+ end
2295
+ end
2296
+
2297
+ [false, true].each do |nullable|
2298
+ context "nullable=#{nullable}" do
2299
+ it 'infers optional: from null:' do
2300
+ eval <<~EOS
2301
+ class AdvertBelongsTo < ActiveRecord::Base
2302
+ declare_schema { }
2303
+ belongs_to :ad_category, null: #{nullable}
2304
+ end
2305
+ EOS
2306
+ expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_flag[nullable])
2307
+ expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(nullable)
2308
+ end
2309
+
2310
+ it 'infers null: from optional:' do
2311
+ eval <<~EOS
2312
+ class AdvertBelongsTo < ActiveRecord::Base
2313
+ declare_schema { }
2314
+ belongs_to :ad_category, optional: #{nullable}
2315
+ end
2316
+ EOS
2317
+ expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_flag[nullable])
2318
+ expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(nullable)
2319
+ end
2320
+ end
2321
+ end
2322
+
2323
+ it 'deprecates limit:' do
2324
+ expect(ActiveSupport::Deprecation).to receive(:warn).with("belongs_to limit: is deprecated since it is now inferred")
2325
+ eval <<~EOS
2326
+ class UsingLimit < ActiveRecord::Base
2327
+ declare_schema { }
2328
+ belongs_to :ad_category, limit: 4
2329
+ end
2330
+ EOS
2321
2331
  end
2322
2332
  end
2323
2333
 
2324
- [false, true].each do |nullable|
2325
- context "nullable=#{nullable}" do
2326
- it 'infers optional: from null:' do
2327
- eval <<~EOS
2328
- class AdvertBelongsTo < ActiveRecord::Base
2329
- declare_schema { }
2330
- belongs_to :ad_category, null: #{nullable}
2331
- end
2332
- EOS
2333
- expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_flag[nullable])
2334
- expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(nullable)
2334
+ context 'when parent object PKs have different limits' do
2335
+ before do
2336
+ class IdDefault < ActiveRecord::Base
2337
+ declare_schema { }
2338
+ end
2339
+ class Id4 < ActiveRecord::Base
2340
+ declare_schema id: :integer do
2341
+ end
2335
2342
  end
2343
+ class Id8 < ActiveRecord::Base
2344
+ declare_schema id: :bigint do
2345
+ end
2346
+ end
2347
+ class Fk < ActiveRecord::Base
2348
+ declare_schema { }
2349
+ belongs_to :id_default, (ActiveSupport::VERSION::MAJOR < 5 ? { constraint: false } : {})
2350
+ belongs_to :id4, (ActiveSupport::VERSION::MAJOR < 5 ? { constraint: false } : {})
2351
+ belongs_to :id8, (ActiveSupport::VERSION::MAJOR < 5 ? { constraint: false } : {})
2352
+ end
2353
+ end
2336
2354
 
2337
- it 'infers null: from optional:' do
2338
- eval <<~EOS
2339
- class AdvertBelongsTo < ActiveRecord::Base
2340
- declare_schema { }
2341
- belongs_to :ad_category, optional: #{nullable}
2342
- end
2343
- EOS
2344
- expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_flag[nullable])
2345
- expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(nullable)
2355
+ it 'creates the proper PKs' do
2356
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
2357
+
2358
+ create_id4_defaults = up.split("\n").grep(/create_table :id_defaults/).first
2359
+ expect(create_id4_defaults).to be, up
2360
+ expect(create_id4_defaults).to match(/, id: :bigint/)
2361
+
2362
+ create_id4s = up.split("\n").grep(/create_table :id4s/).first
2363
+ expect(create_id4s).to be, up
2364
+ expect(create_id4s).to match(/, id: :integer/)
2365
+
2366
+ create_id8s = up.split("\n").grep(/create_table :id8s/).first
2367
+ expect(create_id8s).to be, up
2368
+ expect(create_id8s).to match(/, id: :bigint/)
2369
+ end
2370
+
2371
+ it 'infers the correct FK type from the create_table id: type' do
2372
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
2373
+
2374
+ create_fks = up.split("\n").grep(/t\.integer /).map { |command| command.gsub(', null: false', '').gsub(/^ +/, '') }
2375
+ if defined?(SQLite3)
2376
+ create_fks.map! { |command| command.gsub(/limit: [a-z0-9]+/, 'limit: X') }
2377
+ expect(create_fks).to eq([
2378
+ 't.integer :id_default_id, limit: X',
2379
+ 't.integer :id4_id, limit: X',
2380
+ 't.integer :id8_id, limit: X'
2381
+ ]), up
2382
+ else
2383
+ expect(create_fks).to eq([
2384
+ 't.integer :id_default_id, limit: 8',
2385
+ 't.integer :id4_id, limit: 4',
2386
+ 't.integer :id8_id, limit: 8'
2387
+ ]), up
2388
+ end
2389
+ end
2390
+
2391
+ context "when parent objects were migrated before and later definitions don't have explicit id:" do
2392
+ before do
2393
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
2394
+ ActiveRecord::Migration.class_eval up
2395
+ nuke_model_class(IdDefault)
2396
+ nuke_model_class(Id4)
2397
+ nuke_model_class(Id8)
2398
+ nuke_model_class(Fk)
2399
+ ActiveRecord::Base.connection.schema_cache.clear!
2400
+
2401
+
2402
+ class NewIdDefault < ActiveRecord::Base
2403
+ self.table_name = 'id_defaults'
2404
+ declare_schema { }
2405
+ end
2406
+ class NewId4 < ActiveRecord::Base
2407
+ self.table_name = 'id4s'
2408
+ declare_schema { }
2409
+ end
2410
+ class NewId8 < ActiveRecord::Base
2411
+ self.table_name = 'id8s'
2412
+ declare_schema { }
2413
+ end
2414
+ class NewFk < ActiveRecord::Base
2415
+ declare_schema { }
2416
+ belongs_to :new_id_default
2417
+ belongs_to :new_id4
2418
+ belongs_to :new_id8
2419
+ end
2420
+ end
2421
+
2422
+ it 'infers the correct FK :integer limit: ' do
2423
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
2424
+
2425
+ create_fks = up.split("\n").grep(/t\.integer /).map { |command| command.gsub(', null: false', '').gsub(/^ +/, '') }
2426
+ if defined?(SQLite3)
2427
+ create_fks.map! { |command| command.gsub(/limit: [a-z0-9]+/, 'limit: X') }
2428
+ expect(create_fks).to eq([
2429
+ 't.integer :new_id_default_id, limit: X',
2430
+ 't.integer :new_id4_id, limit: X',
2431
+ 't.integer :new_id8_id, limit: X'
2432
+ ]), up
2433
+ else
2434
+ expect(create_fks).to eq([
2435
+ 't.integer :new_id_default_id, limit: 8',
2436
+ 't.integer :new_id4_id, limit: 4',
2437
+ 't.integer :new_id8_id, limit: 8'
2438
+ ]), up
2439
+ end
2346
2440
  end
2347
2441
  end
2348
2442
  end
@@ -2365,13 +2459,13 @@ RSpec.describe 'DeclareSchema Migration Generator' do
2365
2459
  migration_content = File.read(migrations.first)
2366
2460
  first_line = migration_content.split("\n").first
2367
2461
  base_class = first_line.split(' < ').last
2368
- expect(base_class).to eq("(Rails::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)")
2462
+ expect(base_class).to eq("(ActiveSupport::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)")
2369
2463
  end
2370
2464
  end
2371
2465
 
2372
2466
  context 'Does not generate migrations' do
2373
2467
  it 'for aliased fields bigint -> integer limit 8' do
2374
- if Rails::VERSION::MAJOR >= 5 || !ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
2468
+ if ActiveSupport::VERSION::MAJOR >= 5 || !ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
2375
2469
  class Advert < active_record_base_class.constantize
2376
2470
  declare_schema do
2377
2471
  bigint :price
@@ -2383,7 +2477,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
2383
2477
  migrations = Dir.glob('db/migrate/*declare_schema_migration*.rb')
2384
2478
  expect(migrations.size).to eq(1), migrations.inspect
2385
2479
 
2386
- if defined?(Mysql2) && Rails::VERSION::MAJOR < 5
2480
+ if defined?(Mysql2) && ActiveSupport::VERSION::MAJOR < 5
2387
2481
  ActiveRecord::Base.connection.execute("ALTER TABLE adverts ADD PRIMARY KEY (id)")
2388
2482
  end
2389
2483