declare_schema 0.14.3 → 1.0.2

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/workflows/declare_schema_build.yml +22 -23
  4. data/.ruby-version +1 -1
  5. data/Appraisals +8 -0
  6. data/CHANGELOG.md +23 -4
  7. data/Gemfile +3 -2
  8. data/Gemfile.lock +107 -77
  9. data/README.md +18 -8
  10. data/Rakefile +1 -1
  11. data/gemfiles/rails_5_mysql.gemfile +0 -1
  12. data/gemfiles/rails_5_sqlite.gemfile +0 -1
  13. data/gemfiles/rails_6_mysql.gemfile +2 -1
  14. data/gemfiles/rails_6_sqlite.gemfile +2 -1
  15. data/lib/declare_schema/command.rb +1 -1
  16. data/lib/declare_schema/dsl.rb +1 -1
  17. data/lib/declare_schema/extensions/active_record/fields_declaration.rb +0 -18
  18. data/lib/declare_schema/field_declaration_dsl.rb +4 -4
  19. data/lib/declare_schema/model/foreign_key_definition.rb +2 -2
  20. data/lib/declare_schema/model/index_definition.rb +2 -2
  21. data/lib/declare_schema/model/table_options_definition.rb +2 -2
  22. data/lib/declare_schema/model.rb +9 -9
  23. data/lib/declare_schema/schema_change/all.rb +1 -0
  24. data/lib/declare_schema/version.rb +1 -1
  25. data/lib/generators/declare_schema/migration/migrator.rb +6 -6
  26. data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +0 -24
  27. data/spec/lib/declare_schema/interactive_primary_key_spec.rb +0 -67
  28. data/spec/lib/declare_schema/migration_generator_spec.rb +11 -1176
  29. data/spec/lib/declare_schema/model/column_spec.rb +1 -28
  30. data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +1 -94
  31. data/spec/lib/declare_schema/model/index_definition_spec.rb +0 -109
  32. data/spec/lib/declare_schema/model/table_options_definition_spec.rb +2 -65
  33. data/spec/spec_helper.rb +1 -1
  34. metadata +7 -7
  35. data/.github/dependabot.yml +0 -14
@@ -54,1171 +54,6 @@ RSpec.describe 'DeclareSchema Migration Generator' do
54
54
  end
55
55
  end
56
56
 
57
- context 'Using fields' do
58
- # DeclareSchema - Migration Generator
59
- it 'generates migrations' do
60
- ## The migration generator -- introduction
61
-
62
- expect(Generators::DeclareSchema::Migration::Migrator.run).to migrate_up("").and migrate_down("")
63
-
64
- class Advert < ActiveRecord::Base
65
- end
66
-
67
- expect(Generators::DeclareSchema::Migration::Migrator.run).to migrate_up("").and migrate_down("")
68
-
69
- Generators::DeclareSchema::Migration::Migrator.ignore_tables = ["green_fishes"]
70
-
71
- Advert.connection.schema_cache.clear!
72
- Advert.reset_column_information
73
-
74
- class Advert < ActiveRecord::Base
75
- fields do
76
- name :string, limit: 250, null: true
77
- end
78
- end
79
-
80
- up, _ = Generators::DeclareSchema::Migration::Migrator.run.tap do |migrations|
81
- expect(migrations).to(
82
- migrate_up(<<~EOS.strip)
83
- create_table :adverts, id: :bigint#{create_table_charset_and_collation} do |t|
84
- t.string :name, limit: 250, null: true#{charset_and_collation}
85
- end
86
- EOS
87
- .and migrate_down("drop_table :adverts")
88
- )
89
- end
90
-
91
- ActiveRecord::Migration.class_eval(up)
92
- expect(Advert.columns.map(&:name)).to eq(["id", "name"])
93
-
94
- class Advert < ActiveRecord::Base
95
- fields do
96
- name :string, limit: 250, null: true
97
- body :text, null: true
98
- published_at :datetime, null: true
99
- end
100
- end
101
-
102
- Advert.connection.schema_cache.clear!
103
- Advert.reset_column_information
104
-
105
- expect(migrate).to(
106
- migrate_up(<<~EOS.strip)
107
- add_column :adverts, :body, :text#{text_limit}, null: true#{charset_and_collation}
108
- add_column :adverts, :published_at, :datetime, null: true
109
- EOS
110
- .and migrate_down(<<~EOS.strip)
111
- remove_column :adverts, :published_at
112
- remove_column :adverts, :body
113
- EOS
114
- )
115
-
116
- Advert.field_specs.clear # not normally needed
117
- class Advert < ActiveRecord::Base
118
- fields do
119
- name :string, limit: 250, null: true
120
- body :text, null: true
121
- end
122
- end
123
-
124
- expect(migrate).to(
125
- migrate_up("remove_column :adverts, :published_at").and(
126
- migrate_down("add_column :adverts, :published_at, :datetime#{datetime_precision}, null: true")
127
- )
128
- )
129
-
130
- nuke_model_class(Advert)
131
- class Advert < ActiveRecord::Base
132
- fields do
133
- title :string, limit: 250, null: true
134
- body :text, null: true
135
- end
136
- end
137
-
138
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
139
- migrate_up(<<~EOS.strip)
140
- add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
141
- remove_column :adverts, :name
142
- EOS
143
- .and migrate_down(<<~EOS.strip)
144
- add_column :adverts, :name, :string, limit: 250, null: true#{charset_and_collation}
145
- remove_column :adverts, :title
146
- EOS
147
- )
148
-
149
- expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { name: :title })).to(
150
- migrate_up("rename_column :adverts, :name, :title").and(
151
- migrate_down("rename_column :adverts, :title, :name")
152
- )
153
- )
154
-
155
- migrate
156
-
157
- class Advert < ActiveRecord::Base
158
- fields do
159
- title :text, null: true
160
- body :text, null: true
161
- end
162
- end
163
-
164
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
165
- migrate_up("change_column :adverts, :title, :text#{text_limit}, null: true#{charset_and_collation}").and(
166
- migrate_down("change_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}")
167
- )
168
- )
169
-
170
- class Advert < ActiveRecord::Base
171
- fields do
172
- title :string, default: "Untitled", limit: 250, null: true
173
- body :text, null: true
174
- end
175
- end
176
-
177
- expect(migrate).to(
178
- migrate_up(<<~EOS.strip)
179
- change_column :adverts, :title, :string, limit: 250, null: true, default: "Untitled"#{charset_and_collation}
180
- EOS
181
- .and migrate_down(<<~EOS.strip)
182
- change_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
183
- EOS
184
- )
185
-
186
- ### Limits
187
-
188
- class Advert < ActiveRecord::Base
189
- fields do
190
- price :integer, null: true, limit: 2
191
- end
192
- end
193
-
194
- up, _ = Generators::DeclareSchema::Migration::Migrator.run.tap do |migrations|
195
- expect(migrations).to migrate_up("add_column :adverts, :price, :integer, limit: 2, null: true")
196
- end
197
-
198
- # Now run the migration, then change the limit:
199
-
200
- ActiveRecord::Migration.class_eval(up)
201
- class Advert < ActiveRecord::Base
202
- fields do
203
- price :integer, null: true, limit: 3
204
- end
205
- end
206
-
207
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
208
- migrate_up(<<~EOS.strip)
209
- change_column :adverts, :price, :integer, limit: 3, null: true
210
- EOS
211
- .and migrate_down(<<~EOS.strip)
212
- change_column :adverts, :price, :integer, limit: 2, null: true
213
- EOS
214
- )
215
-
216
- ActiveRecord::Migration.class_eval("remove_column :adverts, :price")
217
- class Advert < ActiveRecord::Base
218
- fields do
219
- price :decimal, precision: 4, scale: 1, null: true
220
- end
221
- end
222
-
223
- # Limits are generally not needed for `text` fields, because by default, `text` fields will use the maximum size
224
- # allowed for that database type (0xffffffff for LONGTEXT in MySQL unlimited in Postgres, 1 billion in Sqlite).
225
- # If a `limit` is given, it will only be used in MySQL, to choose the smallest TEXT field that will accommodate
226
- # that limit (0xff for TINYTEXT, 0xffff for TEXT, 0xffffff for MEDIUMTEXT, 0xffffffff for LONGTEXT).
227
-
228
- if defined?(SQLite3)
229
- expect(::DeclareSchema::Model::FieldSpec.mysql_text_limits?).to be_falsey
230
- end
231
-
232
- class Advert < ActiveRecord::Base
233
- fields do
234
- notes :text
235
- description :text, limit: 30000
236
- end
237
- end
238
-
239
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
240
- migrate_up(<<~EOS.strip)
241
- add_column :adverts, :price, :decimal, precision: 4, scale: 1, null: true
242
- add_column :adverts, :notes, :text#{text_limit}, null: false#{charset_and_collation}
243
- add_column :adverts, :description, :text#{', limit: 65535' if defined?(Mysql2)}, null: false#{charset_and_collation}
244
- EOS
245
- )
246
-
247
- Advert.field_specs.delete :price
248
- Advert.field_specs.delete :notes
249
- Advert.field_specs.delete :description
250
-
251
- # In MySQL, limits are applied, rounded up:
252
-
253
- if defined?(Mysql2)
254
- expect(::DeclareSchema::Model::FieldSpec.mysql_text_limits?).to be_truthy
255
-
256
- class Advert < ActiveRecord::Base
257
- fields do
258
- notes :text
259
- description :text, limit: 250
260
- end
261
- end
262
-
263
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
264
- migrate_up(<<~EOS.strip)
265
- add_column :adverts, :notes, :text, limit: 4294967295, null: false#{charset_and_collation}
266
- add_column :adverts, :description, :text, limit: 255, null: false#{charset_and_collation}
267
- EOS
268
- )
269
-
270
- Advert.field_specs.delete :notes
271
-
272
- # Limits that are too high for MySQL will raise an exception.
273
-
274
- expect do
275
- class Advert < ActiveRecord::Base
276
- fields do
277
- notes :text
278
- description :text, limit: 0x1_0000_0000
279
- end
280
- end
281
- end.to raise_exception(ArgumentError, "limit of 4294967296 is too large for MySQL")
282
-
283
- Advert.field_specs.delete :notes
284
-
285
- # And in MySQL, unstated text limits are treated as the maximum (LONGTEXT) limit.
286
-
287
- # To start, we'll set the database schema for `description` to match the above limit of 250.
288
-
289
- Advert.connection.execute "ALTER TABLE adverts ADD COLUMN description TINYTEXT"
290
- Advert.connection.schema_cache.clear!
291
- Advert.reset_column_information
292
- expect(Advert.connection.tables - Generators::DeclareSchema::Migration::Migrator.always_ignore_tables).
293
- to eq(["adverts"])
294
- expect(Advert.columns.map(&:name)).to eq(["id", "body", "title", "description"])
295
-
296
- # Now migrate to an unstated text limit:
297
-
298
- class Advert < ActiveRecord::Base
299
- fields do
300
- description :text
301
- end
302
- end
303
-
304
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
305
- migrate_up(<<~EOS.strip)
306
- change_column :adverts, :description, :text, limit: 4294967295, null: false#{charset_and_collation}
307
- EOS
308
- .and migrate_down(<<~EOS.strip)
309
- change_column :adverts, :description, :text#{', limit: 255' if defined?(Mysql2)}, null: true#{charset_and_collation}
310
- EOS
311
- )
312
-
313
- # And migrate to a stated text limit that is the same as the unstated one:
314
-
315
- class Advert < ActiveRecord::Base
316
- fields do
317
- description :text, limit: 0xffffffff
318
- end
319
- end
320
-
321
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
322
- migrate_up(<<~EOS.strip)
323
- change_column :adverts, :description, :text, limit: 4294967295, null: false#{charset_and_collation}
324
- EOS
325
- .and migrate_down(<<~EOS.strip)
326
- change_column :adverts, :description, :text#{', limit: 255' if defined?(Mysql2)}, null: true#{charset_and_collation}
327
- EOS
328
- )
329
- end
330
-
331
- Advert.field_specs.clear
332
- Advert.connection.schema_cache.clear!
333
- Advert.reset_column_information
334
- class Advert < ActiveRecord::Base
335
- fields do
336
- name :string, limit: 250, null: true
337
- end
338
- end
339
-
340
- up = Generators::DeclareSchema::Migration::Migrator.run.first
341
- ActiveRecord::Migration.class_eval up
342
-
343
- Advert.connection.schema_cache.clear!
344
- Advert.reset_column_information
345
-
346
- ### Foreign Keys
347
-
348
- # DeclareSchema extends the `belongs_to` macro so that it also declares the
349
- # foreign-key field. It also generates an index on the field.
350
-
351
- class Category < ActiveRecord::Base; end
352
- class Advert < ActiveRecord::Base
353
- fields do
354
- name :string, limit: 250, null: true
355
- end
356
- belongs_to :category
357
- end
358
-
359
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
360
- migrate_up(<<~EOS.strip)
361
- add_column :adverts, :category_id, :integer, limit: 8, null: false
362
- add_index :adverts, [:category_id], name: :on_category_id
363
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id" if defined?(Mysql2)}
364
- EOS
365
- .and migrate_down(<<~EOS.strip)
366
- #{"remove_foreign_key :adverts, name: :index_adverts_on_category_id" if defined?(Mysql2)}
367
- remove_index :adverts, name: :on_category_id
368
- remove_column :adverts, :category_id
369
- EOS
370
- )
371
-
372
- Advert.field_specs.delete(:category_id)
373
- Advert.index_definitions.delete_if { |spec| spec.fields==["category_id"] }
374
-
375
- # If you specify a custom foreign key, the migration generator observes that:
376
-
377
- class Category < ActiveRecord::Base; end
378
- class Advert < ActiveRecord::Base
379
- fields { }
380
- belongs_to :category, foreign_key: "c_id", class_name: 'Category'
381
- end
382
-
383
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
384
- migrate_up(<<~EOS.strip)
385
- add_column :adverts, :c_id, :integer, limit: 8, null: false
386
- add_index :adverts, [:c_id], name: :on_c_id
387
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
388
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
389
- EOS
390
- )
391
-
392
- Advert.field_specs.delete(:c_id)
393
- Advert.index_definitions.delete_if { |spec| spec.fields == ["c_id"] }
394
-
395
- # You can avoid generating the index by specifying `index: false`
396
-
397
- class Category < ActiveRecord::Base; end
398
- class Advert < ActiveRecord::Base
399
- fields { }
400
- belongs_to :category, index: false
401
- end
402
-
403
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
404
- migrate_up(<<~EOS.strip)
405
- add_column :adverts, :category_id, :integer, limit: 8, null: false
406
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
407
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
408
- EOS
409
- )
410
-
411
- Advert.field_specs.delete(:category_id)
412
- Advert.index_definitions.delete_if { |spec| spec.fields == ["category_id"] }
413
-
414
- # You can specify the index name with :index
415
-
416
- class Category < ActiveRecord::Base; end
417
- class Advert < ActiveRecord::Base
418
- fields { }
419
- belongs_to :category, index: 'my_index'
420
- end
421
-
422
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
423
- migrate_up(<<~EOS.strip)
424
- add_column :adverts, :category_id, :integer, limit: 8, null: false
425
- add_index :adverts, [:category_id], name: :my_index
426
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
427
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
428
- EOS
429
- )
430
-
431
- Advert.field_specs.delete(:category_id)
432
- Advert.index_definitions.delete_if { |spec| spec.fields == ["category_id"] }
433
-
434
- ### Timestamps and Optimistic Locking
435
-
436
- # `updated_at` and `created_at` can be declared with the shorthand `timestamps`.
437
- # Similarly, `lock_version` can be declared with the "shorthand" `optimistic_lock`.
438
-
439
- class Advert < ActiveRecord::Base
440
- fields do
441
- timestamps
442
- optimistic_lock
443
- end
444
- end
445
-
446
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
447
- migrate_up(<<~EOS.strip)
448
- add_column :adverts, :created_at, :datetime, null: true
449
- add_column :adverts, :updated_at, :datetime, null: true
450
- add_column :adverts, :lock_version, :integer#{lock_version_limit}, null: false, default: 1
451
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
452
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
453
- EOS
454
- .and migrate_down(<<~EOS.strip)
455
- #{"remove_foreign_key :adverts, name: :index_adverts_on_c_id\n" +
456
- "remove_foreign_key :adverts, name: :index_adverts_on_category_id" if defined?(Mysql2)}
457
- remove_column :adverts, :lock_version
458
- remove_column :adverts, :updated_at
459
- remove_column :adverts, :created_at
460
- EOS
461
- )
462
-
463
- Advert.field_specs.delete(:updated_at)
464
- Advert.field_specs.delete(:created_at)
465
- Advert.field_specs.delete(:lock_version)
466
-
467
- ### Indices
468
-
469
- # You can add an index to a field definition
470
-
471
- class Advert < ActiveRecord::Base
472
- fields do
473
- title :string, index: true, limit: 250, null: true
474
- end
475
- end
476
-
477
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
478
- migrate_up(<<~EOS.strip)
479
- add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
480
- add_index :adverts, [:title], name: :on_title
481
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
482
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
483
- EOS
484
- )
485
-
486
- Advert.index_definitions.delete_if { |spec| spec.fields==["title"] }
487
-
488
- # You can ask for a unique index
489
-
490
- class Advert < ActiveRecord::Base
491
- fields do
492
- title :string, index: true, unique: true, null: true, limit: 250
493
- end
494
- end
495
-
496
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
497
- migrate_up(<<~EOS.strip)
498
- add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
499
- add_index :adverts, [:title], name: :on_title, unique: true
500
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
501
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
502
- EOS
503
- )
504
-
505
- Advert.index_definitions.delete_if { |spec| spec.fields == ["title"] }
506
-
507
- # You can specify the name for the index
508
-
509
- class Advert < ActiveRecord::Base
510
- fields do
511
- title :string, index: 'my_index', limit: 250, null: true
512
- end
513
- end
514
-
515
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
516
- migrate_up(<<~EOS.strip)
517
- add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
518
- add_index :adverts, [:title], name: :my_index
519
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
520
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
521
- EOS
522
- )
523
-
524
- Advert.index_definitions.delete_if { |spec| spec.fields==["title"] }
525
-
526
- # You can ask for an index outside of the fields block
527
-
528
- class Advert < ActiveRecord::Base
529
- index :title
530
- end
531
-
532
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
533
- migrate_up(<<~EOS.strip)
534
- add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
535
- add_index :adverts, [:title], name: :on_title
536
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
537
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
538
- EOS
539
- )
540
-
541
- Advert.index_definitions.delete_if { |spec| spec.fields == ["title"] }
542
-
543
- # The available options for the index function are `:unique` and `:name`
544
-
545
- class Advert < ActiveRecord::Base
546
- index :title, unique: true, name: 'my_index'
547
- end
548
-
549
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
550
- migrate_up(<<~EOS.strip)
551
- add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
552
- add_index :adverts, [:title], name: :my_index, unique: true
553
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
554
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
555
- EOS
556
- )
557
-
558
- Advert.index_definitions.delete_if { |spec| spec.fields == ["title"] }
559
-
560
- # You can create an index on more than one field
561
-
562
- class Advert < ActiveRecord::Base
563
- index [:title, :category_id]
564
- end
565
-
566
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
567
- migrate_up(<<~EOS.strip)
568
- add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
569
- add_index :adverts, [:title, :category_id], name: :on_title_and_category_id
570
- #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
571
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
572
- EOS
573
- )
574
-
575
- Advert.index_definitions.delete_if { |spec| spec.fields==["title", "category_id"] }
576
-
577
- # Finally, you can specify that the migration generator should completely ignore an
578
- # index by passing its name to ignore_index in the model.
579
- # This is helpful for preserving indices that can't be automatically generated, such as prefix indices in MySQL.
580
-
581
- ### Rename a table
582
-
583
- # The migration generator respects the `set_table_name` declaration, although as before,
584
- # we need to explicitly tell the generator that we want a rename rather than a create and a drop.
585
-
586
- class Advert < ActiveRecord::Base
587
- self.table_name = "ads"
588
- fields do
589
- title :string, limit: 250, null: true
590
- body :text, null: true
591
- end
592
- end
593
-
594
- Advert.connection.schema_cache.clear!
595
- Advert.reset_column_information
596
-
597
- expect(Generators::DeclareSchema::Migration::Migrator.run("adverts" => "ads")).to(
598
- migrate_up(<<~EOS.strip)
599
- rename_table :adverts, :ads
600
- add_column :ads, :title, :string, limit: 250, null: true#{charset_and_collation}
601
- add_column :ads, :body, :text#{', limit: 4294967295' if defined?(Mysql2)}, null: true#{charset_and_collation}
602
- #{if defined?(Mysql2)
603
- "add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
604
- "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id"
605
- end}
606
- EOS
607
- .and migrate_down(<<~EOS.strip)
608
- #{if defined?(Mysql2)
609
- "remove_foreign_key :adverts, name: :index_adverts_on_c_id\n" +
610
- "remove_foreign_key :adverts, name: :index_adverts_on_category_id"
611
- end}
612
- remove_column :ads, :body
613
- remove_column :ads, :title
614
- rename_table :ads, :adverts
615
- EOS
616
- )
617
-
618
- # Set the table name back to what it should be and confirm we're in sync:
619
-
620
- nuke_model_class(Advert)
621
-
622
- class Advert < ActiveRecord::Base
623
- self.table_name = "adverts"
624
- end
625
-
626
- expect(Generators::DeclareSchema::Migration::Migrator.run).to eq(["", ""])
627
-
628
- ### Rename a table
629
-
630
- # As with renaming columns, we have to tell the migration generator about the rename. Here we create a new class 'Advertisement', and tell ActiveRecord to forget about the Advert class. This requires code that shouldn't be shown to impressionable children.
631
-
632
- nuke_model_class(Advert)
633
-
634
- class Advertisement < ActiveRecord::Base
635
- fields do
636
- title :string, limit: 250, null: true
637
- body :text, null: true
638
- end
639
- end
640
-
641
- expect(Generators::DeclareSchema::Migration::Migrator.run("adverts" => "advertisements")).to(
642
- migrate_up(<<~EOS.strip)
643
- rename_table :adverts, :advertisements
644
- add_column :advertisements, :title, :string, limit: 250, null: true#{charset_and_collation}
645
- add_column :advertisements, :body, :text#{', limit: 4294967295' if defined?(Mysql2)}, null: true#{charset_and_collation}
646
- remove_column :advertisements, :name
647
- EOS
648
- .and migrate_down(<<~EOS.strip)
649
- add_column :advertisements, :name, :string, limit: 250, null: true#{charset_and_collation}
650
- remove_column :advertisements, :body
651
- remove_column :advertisements, :title
652
- rename_table :advertisements, :adverts
653
- EOS
654
- )
655
-
656
- ### Drop a table
657
-
658
- nuke_model_class(Advertisement)
659
-
660
- # If you delete a model, the migration generator will create a `drop_table` migration.
661
-
662
- # Dropping tables is where the automatic down-migration really comes in handy:
663
-
664
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
665
- migrate_up(<<~EOS.strip)
666
- drop_table :adverts
667
- EOS
668
- .and migrate_down(<<~EOS.strip)
669
- create_table "adverts"#{table_options}, force: :cascade do |t|
670
- t.string "name", limit: 250#{charset_and_collation}
671
- end
672
- EOS
673
- )
674
-
675
- ## STI
676
-
677
- ### Adding an STI subclass
678
-
679
- # Adding a subclass or two should introduce the 'type' column and no other changes
680
-
681
- class Advert < ActiveRecord::Base
682
- fields do
683
- body :text, null: true
684
- title :string, default: "Untitled", limit: 250, null: true
685
- end
686
- end
687
- up = Generators::DeclareSchema::Migration::Migrator.run.first
688
- ActiveRecord::Migration.class_eval(up)
689
-
690
- class FancyAdvert < Advert
691
- end
692
- class SuperFancyAdvert < FancyAdvert
693
- end
694
-
695
- up, _ = Generators::DeclareSchema::Migration::Migrator.run do |migrations|
696
- expect(migrations).to(
697
- migrate_up(<<~EOS.strip)
698
- add_column :adverts, :type, :string, limit: 250, null: true#{charset_and_collation}
699
- add_index :adverts, [:type], name: :on_type
700
- EOS
701
- .and migrate_down(<<~EOS.strip)
702
- remove_column :adverts, :type
703
- remove_index :adverts, name: :on_type
704
- EOS
705
- )
706
- end
707
-
708
- Advert.field_specs.delete(:type)
709
- nuke_model_class(SuperFancyAdvert)
710
- nuke_model_class(FancyAdvert)
711
- Advert.index_definitions.delete_if { |spec| spec.fields==["type"] }
712
-
713
- ## Coping with multiple changes
714
-
715
- # The migration generator is designed to create complete migrations even if many changes to the models have taken place.
716
-
717
- # First let's confirm we're in a known state. One model, 'Advert', with a string 'title' and text 'body':
718
-
719
- ActiveRecord::Migration.class_eval up.gsub(/.*type.*/, '')
720
- Advert.connection.schema_cache.clear!
721
- Advert.reset_column_information
722
-
723
- expect(Advert.connection.tables - Generators::DeclareSchema::Migration::Migrator.always_ignore_tables).
724
- to eq(["adverts"])
725
- expect(Advert.columns.map(&:name).sort).to eq(["body", "id", "title"])
726
- expect(Generators::DeclareSchema::Migration::Migrator.run).to eq(["", ""])
727
-
728
-
729
- ### Rename a column and change the default
730
-
731
- Advert.field_specs.clear
732
-
733
- class Advert < ActiveRecord::Base
734
- fields do
735
- name :string, default: "No Name", limit: 250, null: true
736
- body :text, null: true
737
- end
738
- end
739
-
740
- expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { title: :name })).to(
741
- migrate_up(<<~EOS.strip)
742
- rename_column :adverts, :title, :name
743
- change_column :adverts, :name, :string, limit: 250, null: true, default: "No Name"#{charset_and_collation}
744
- EOS
745
- .and migrate_down(<<~EOS.strip)
746
- change_column :adverts, :name, :string, limit: 250, null: true, default: "Untitled"#{charset_and_collation}
747
- rename_column :adverts, :name, :title
748
- EOS
749
- )
750
-
751
- ### Rename a table and add a column
752
-
753
- nuke_model_class(Advert)
754
- class Ad < ActiveRecord::Base
755
- fields do
756
- title :string, default: "Untitled", limit: 250
757
- body :text, null: true
758
- created_at :datetime
759
- end
760
- end
761
-
762
- expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: :ads)).to(
763
- migrate_up(<<~EOS.strip)
764
- rename_table :adverts, :ads
765
- add_column :ads, :created_at, :datetime, null: false
766
- change_column :ads, :title, :string, limit: 250, null: false, default: \"Untitled\"#{charset_and_collation}
767
- EOS
768
- )
769
-
770
- class Advert < ActiveRecord::Base
771
- fields do
772
- body :text, null: true
773
- title :string, default: "Untitled", limit: 250, null: true
774
- end
775
- end
776
-
777
- ## Legacy Keys
778
-
779
- # DeclareSchema has some support for legacy keys.
780
-
781
- nuke_model_class(Ad)
782
-
783
- class Advert < ActiveRecord::Base
784
- fields do
785
- body :text, null: true
786
- end
787
- self.primary_key = "advert_id"
788
- end
789
-
790
- expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { id: :advert_id })).to(
791
- migrate_up(<<~EOS.strip)
792
- rename_column :adverts, :id, :advert_id
793
- EOS
794
- )
795
-
796
- Advert.connection.schema_cache.clear!
797
- Advert.reset_column_information
798
-
799
- nuke_model_class(Advert)
800
- ActiveRecord::Base.connection.execute("drop table `adverts`;")
801
-
802
- if !defined?(SQLite3) && ActiveSupport::VERSION::MAJOR >= 5
803
- class Advert < ActiveRecord::Base
804
- def self.disable_auto_increment
805
- true
806
- end
807
-
808
- fields do
809
- description :text, limit: 250, null: true
810
- end
811
- end
812
-
813
- up, _ = Generators::DeclareSchema::Migration::Migrator.run.tap do |migrations|
814
- expect(migrations).to(
815
- migrate_up(<<~EOS.strip)
816
- create_table :adverts, id: false, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
817
- t.integer :id, limit: 8, auto_increment: false, primary_key: true
818
- t.text :description, limit: 255, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
819
- end
820
- EOS
821
- .and migrate_down("drop_table :adverts")
822
- )
823
- end
824
- end
825
-
826
- ## DSL
827
-
828
- # The DSL allows lambdas and constants
829
-
830
- class User < ActiveRecord::Base
831
- fields do
832
- company :string, limit: 250, ruby_default: -> { "BigCorp" }
833
- end
834
- end
835
- expect(User.field_specs.keys).to eq(['company'])
836
- expect(User.field_specs['company'].options[:ruby_default]&.call).to eq("BigCorp")
837
-
838
- ## validates
839
-
840
- # DeclareSchema can accept a validates hash in the field options.
841
-
842
- class Ad < ActiveRecord::Base
843
- class << self
844
- def validates(field_name, options)
845
- end
846
- end
847
- end
848
- expect(Ad).to receive(:validates).with(:company, presence: true, uniqueness: { case_sensitive: false })
849
- class Ad < ActiveRecord::Base
850
- fields do
851
- company :string, limit: 250, index: true, unique: true, validates: { presence: true, uniqueness: { case_sensitive: false } }
852
- end
853
- self.primary_key = "advert_id"
854
- end
855
- up, _down = Generators::DeclareSchema::Migration::Migrator.run
856
- ActiveRecord::Migration.class_eval(up)
857
- expect(Ad.field_specs['company'].options[:validates].inspect).to eq("{:presence=>true, :uniqueness=>{:case_sensitive=>false}}")
858
- end
859
-
860
- context 'models with the same parent foreign key relation' do
861
- before do
862
- class Category < ActiveRecord::Base
863
- fields do
864
- name :string, limit: 250, null: true
865
- end
866
- end
867
- class Advertiser < ActiveRecord::Base
868
- fields do
869
- name :string, limit: 250, null: true
870
- end
871
- belongs_to :category, limit: 8
872
- end
873
- class Affiliate < ActiveRecord::Base
874
- fields do
875
- name :string, limit: 250, null: true
876
- end
877
- belongs_to :category, limit: 8
878
- end
879
- end
880
-
881
- it 'will genereate unique constraint names' do
882
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
883
- migrate_up(<<~EOS.strip)
884
- create_table :categories, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
885
- t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
886
- end
887
- create_table :advertisers, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
888
- t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
889
- t.integer :category_id, limit: 8, null: false
890
- end
891
- create_table :affiliates, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
892
- t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
893
- t.integer :category_id, limit: 8, null: false
894
- end
895
- add_index :advertisers, [:category_id], name: :on_category_id
896
- add_index :affiliates, [:category_id], name: :on_category_id
897
- add_foreign_key :advertisers, :categories, column: :category_id, name: :index_advertisers_on_category_id
898
- add_foreign_key :affiliates, :categories, column: :category_id, name: :index_affiliates_on_category_id
899
- EOS
900
- )
901
- migrate
902
-
903
- nuke_model_class(Advertiser)
904
- nuke_model_class(Affiliate)
905
- end
906
- end if !defined?(SQLite3)
907
-
908
- describe 'serialize' do
909
- before do
910
- class Ad < ActiveRecord::Base
911
- @serialize_args = []
912
-
913
- class << self
914
- attr_reader :serialize_args
915
-
916
- def serialize(*args)
917
- @serialize_args << args
918
- end
919
- end
920
- end
921
- end
922
-
923
- describe 'untyped' do
924
- it 'allows serialize: true' do
925
- class Ad < ActiveRecord::Base
926
- fields do
927
- allow_list :text, limit: 0xFFFF, serialize: true
928
- end
929
- end
930
-
931
- expect(Ad.serialize_args).to eq([[:allow_list]])
932
- end
933
-
934
- it 'converts defaults with .to_yaml' do
935
- class Ad < ActiveRecord::Base
936
- fields do
937
- allow_list :string, limit: 250, serialize: true, null: true, default: []
938
- allow_hash :string, limit: 250, serialize: true, null: true, default: {}
939
- allow_string :string, limit: 250, serialize: true, null: true, default: ['abc']
940
- allow_null :string, limit: 250, serialize: true, null: true, default: nil
941
- end
942
- end
943
-
944
- expect(Ad.field_specs['allow_list'].default).to eq("--- []\n")
945
- expect(Ad.field_specs['allow_hash'].default).to eq("--- {}\n")
946
- expect(Ad.field_specs['allow_string'].default).to eq("---\n- abc\n")
947
- expect(Ad.field_specs['allow_null'].default).to eq(nil)
948
- end
949
- end
950
-
951
- describe 'Array' do
952
- it 'allows serialize: Array' do
953
- class Ad < ActiveRecord::Base
954
- fields do
955
- allow_list :string, limit: 250, serialize: Array, null: true
956
- end
957
- end
958
-
959
- expect(Ad.serialize_args).to eq([[:allow_list, Array]])
960
- end
961
-
962
- it 'allows Array defaults' do
963
- class Ad < ActiveRecord::Base
964
- fields do
965
- allow_list :string, limit: 250, serialize: Array, null: true, default: [2]
966
- allow_string :string, limit: 250, serialize: Array, null: true, default: ['abc']
967
- allow_empty :string, limit: 250, serialize: Array, null: true, default: []
968
- allow_null :string, limit: 250, serialize: Array, null: true, default: nil
969
- end
970
- end
971
-
972
- expect(Ad.field_specs['allow_list'].default).to eq("---\n- 2\n")
973
- expect(Ad.field_specs['allow_string'].default).to eq("---\n- abc\n")
974
- expect(Ad.field_specs['allow_empty'].default).to eq(nil)
975
- expect(Ad.field_specs['allow_null'].default).to eq(nil)
976
- end
977
- end
978
-
979
- describe 'Hash' do
980
- it 'allows serialize: Hash' do
981
- class Ad < ActiveRecord::Base
982
- fields do
983
- allow_list :string, limit: 250, serialize: Hash, null: true
984
- end
985
- end
986
-
987
- expect(Ad.serialize_args).to eq([[:allow_list, Hash]])
988
- end
989
-
990
- it 'allows Hash defaults' do
991
- class Ad < ActiveRecord::Base
992
- fields do
993
- allow_loc :string, limit: 250, serialize: Hash, null: true, default: { 'state' => 'CA' }
994
- allow_hash :string, limit: 250, serialize: Hash, null: true, default: {}
995
- allow_null :string, limit: 250, serialize: Hash, null: true, default: nil
996
- end
997
- end
998
-
999
- expect(Ad.field_specs['allow_loc'].default).to eq("---\nstate: CA\n")
1000
- expect(Ad.field_specs['allow_hash'].default).to eq(nil)
1001
- expect(Ad.field_specs['allow_null'].default).to eq(nil)
1002
- end
1003
- end
1004
-
1005
- describe 'JSON' do
1006
- it 'allows serialize: JSON' do
1007
- class Ad < ActiveRecord::Base
1008
- fields do
1009
- allow_list :string, limit: 250, serialize: JSON
1010
- end
1011
- end
1012
-
1013
- expect(Ad.serialize_args).to eq([[:allow_list, JSON]])
1014
- end
1015
-
1016
- it 'allows JSON defaults' do
1017
- class Ad < ActiveRecord::Base
1018
- fields do
1019
- allow_hash :string, limit: 250, serialize: JSON, null: true, default: { 'state' => 'CA' }
1020
- allow_empty_array :string, limit: 250, serialize: JSON, null: true, default: []
1021
- allow_empty_hash :string, limit: 250, serialize: JSON, null: true, default: {}
1022
- allow_null :string, limit: 250, serialize: JSON, null: true, default: nil
1023
- end
1024
- end
1025
-
1026
- expect(Ad.field_specs['allow_hash'].default).to eq("{\"state\":\"CA\"}")
1027
- expect(Ad.field_specs['allow_empty_array'].default).to eq("[]")
1028
- expect(Ad.field_specs['allow_empty_hash'].default).to eq("{}")
1029
- expect(Ad.field_specs['allow_null'].default).to eq(nil)
1030
- end
1031
- end
1032
-
1033
- class ValueClass
1034
- delegate :present?, :inspect, to: :@value
1035
-
1036
- def initialize(value)
1037
- @value = value
1038
- end
1039
-
1040
- class << self
1041
- def dump(object)
1042
- if object&.present?
1043
- object.inspect
1044
- end
1045
- end
1046
-
1047
- def load(serialized)
1048
- if serialized
1049
- raise 'not used ???'
1050
- end
1051
- end
1052
- end
1053
- end
1054
-
1055
- describe 'custom coder' do
1056
- it 'allows serialize: ValueClass' do
1057
- class Ad < ActiveRecord::Base
1058
- fields do
1059
- allow_list :string, limit: 250, serialize: ValueClass
1060
- end
1061
- end
1062
-
1063
- expect(Ad.serialize_args).to eq([[:allow_list, ValueClass]])
1064
- end
1065
-
1066
- it 'allows ValueClass defaults' do
1067
- class Ad < ActiveRecord::Base
1068
- fields do
1069
- allow_hash :string, limit: 250, serialize: ValueClass, null: true, default: ValueClass.new([2])
1070
- allow_empty_array :string, limit: 250, serialize: ValueClass, null: true, default: ValueClass.new([])
1071
- allow_null :string, limit: 250, serialize: ValueClass, null: true, default: nil
1072
- end
1073
- end
1074
-
1075
- expect(Ad.field_specs['allow_hash'].default).to eq("[2]")
1076
- expect(Ad.field_specs['allow_empty_array'].default).to eq(nil)
1077
- expect(Ad.field_specs['allow_null'].default).to eq(nil)
1078
- end
1079
- end
1080
-
1081
- it 'disallows serialize: with a non-string column type' do
1082
- expect do
1083
- class Ad < ActiveRecord::Base
1084
- fields do
1085
- allow_list :integer, limit: 8, serialize: true
1086
- end
1087
- end
1088
- end.to raise_exception(ArgumentError, /must be :string or :text/)
1089
- end
1090
- end
1091
-
1092
- context "for Rails #{ActiveSupport::VERSION::MAJOR}" do
1093
- let(:optional_true) { { optional: true } }
1094
- let(:optional_false) { { optional: false } }
1095
- let(:optional_flag) { { false => optional_false, true => optional_true } }
1096
-
1097
- describe 'belongs_to' do
1098
- before do
1099
- unless defined?(AdCategory)
1100
- class AdCategory < ActiveRecord::Base
1101
- fields { }
1102
- end
1103
- end
1104
-
1105
- class Advert < ActiveRecord::Base
1106
- fields do
1107
- name :string, limit: 250, null: true
1108
- category_id :integer, limit: 8
1109
- nullable_category_id :integer, limit: 8, null: true
1110
- end
1111
- end
1112
- up = Generators::DeclareSchema::Migration::Migrator.run.first
1113
- ActiveRecord::Migration.class_eval(up)
1114
- end
1115
-
1116
- it 'passes through optional: when given' do
1117
- class AdvertBelongsTo < ActiveRecord::Base
1118
- self.table_name = 'adverts'
1119
- fields { }
1120
- reset_column_information
1121
- belongs_to :ad_category, optional: true
1122
- end
1123
- expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_true)
1124
- end
1125
-
1126
- describe 'contradictory settings' do # contradictory settings are ok--for example, during migration
1127
- it 'passes through optional: true, null: false' do
1128
- class AdvertBelongsTo < ActiveRecord::Base
1129
- self.table_name = 'adverts'
1130
- fields { }
1131
- reset_column_information
1132
- belongs_to :ad_category, optional: true, null: false
1133
- end
1134
- expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_true)
1135
- expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(false)
1136
- end
1137
-
1138
- it 'passes through optional: false, null: true' do
1139
- class AdvertBelongsTo < ActiveRecord::Base
1140
- self.table_name = 'adverts'
1141
- fields { }
1142
- reset_column_information
1143
- belongs_to :ad_category, optional: false, null: true
1144
- end
1145
- expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_false)
1146
- expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(true)
1147
- end
1148
- end
1149
-
1150
- [false, true].each do |nullable|
1151
- context "nullable=#{nullable}" do
1152
- it 'infers optional: from null:' do
1153
- eval <<~EOS
1154
- class AdvertBelongsTo < ActiveRecord::Base
1155
- fields { }
1156
- belongs_to :ad_category, null: #{nullable}
1157
- end
1158
- EOS
1159
- expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_flag[nullable])
1160
- expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(nullable)
1161
- end
1162
-
1163
- it 'infers null: from optional:' do
1164
- eval <<~EOS
1165
- class AdvertBelongsTo < ActiveRecord::Base
1166
- fields { }
1167
- belongs_to :ad_category, optional: #{nullable}
1168
- end
1169
- EOS
1170
- expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_flag[nullable])
1171
- expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(nullable)
1172
- end
1173
- end
1174
- end
1175
- end
1176
- end
1177
-
1178
- describe 'migration base class' do
1179
- it 'adapts to Rails 4' do
1180
- class Advert < active_record_base_class.constantize
1181
- fields do
1182
- title :string, limit: 100
1183
- end
1184
- end
1185
-
1186
- generate_migrations '-n', '-m'
1187
-
1188
- migrations = Dir.glob('db/migrate/*declare_schema_migration*.rb')
1189
- expect(migrations.size).to eq(1), migrations.inspect
1190
-
1191
- migration_content = File.read(migrations.first)
1192
- first_line = migration_content.split("\n").first
1193
- base_class = first_line.split(' < ').last
1194
- expect(base_class).to eq("(ActiveRecord::Migration[4.2])")
1195
- end
1196
- end
1197
-
1198
- context 'Does not generate migrations' do
1199
- it 'for aliased fields bigint -> integer limit 8' do
1200
- class Advert < active_record_base_class.constantize
1201
- fields do
1202
- price :bigint
1203
- end
1204
- end
1205
-
1206
- generate_migrations '-n', '-m'
1207
-
1208
- migrations = Dir.glob('db/migrate/*declare_schema_migration*.rb')
1209
- expect(migrations.size).to eq(1), migrations.inspect
1210
-
1211
- class Advert < active_record_base_class.constantize
1212
- fields do
1213
- price :integer, limit: 8
1214
- end
1215
- end
1216
-
1217
- expect { generate_migrations '-n', '-g' }.to output("Database and models match -- nothing to change\n").to_stdout
1218
- end
1219
- end
1220
- end
1221
-
1222
57
  context 'Using declare_schema' do
1223
58
  # DeclareSchema - Migration Generator
1224
59
  it 'generates migrations' do
@@ -1758,7 +593,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1758
593
  Advert.connection.schema_cache.clear!
1759
594
  Advert.reset_column_information
1760
595
 
1761
- expect(Generators::DeclareSchema::Migration::Migrator.run("adverts" => "ads")).to(
596
+ expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: "ads")).to(
1762
597
  migrate_up(<<~EOS.strip)
1763
598
  rename_table :adverts, :ads
1764
599
  add_column :ads, :title, :string, limit: 250, null: true#{charset_and_collation}
@@ -1802,7 +637,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1802
637
  end
1803
638
  end
1804
639
 
1805
- expect(Generators::DeclareSchema::Migration::Migrator.run("adverts" => "advertisements")).to(
640
+ expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: "advertisements")).to(
1806
641
  migrate_up(<<~EOS.strip)
1807
642
  rename_table :adverts, :advertisements
1808
643
  add_column :advertisements, :title, :string, limit: 250, null: true#{charset_and_collation}
@@ -1999,19 +834,19 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1999
834
  context 'models with the same parent foreign key relation' do
2000
835
  before do
2001
836
  class Category < ActiveRecord::Base
2002
- fields do
2003
- name :string, limit: 250, null: true
837
+ declare_schema do
838
+ string :name, limit: 250, null: true
2004
839
  end
2005
840
  end
2006
841
  class Advertiser < ActiveRecord::Base
2007
- fields do
2008
- name :string, limit: 250, null: true
842
+ declare_schema do
843
+ string :name, limit: 250, null: true
2009
844
  end
2010
845
  belongs_to :category, limit: 8
2011
846
  end
2012
847
  class Affiliate < ActiveRecord::Base
2013
- fields do
2014
- name :string, limit: 250, null: true
848
+ declare_schema do
849
+ string :name, limit: 250, null: true
2015
850
  end
2016
851
  belongs_to :category, limit: 8
2017
852
  end
@@ -2339,9 +1174,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
2339
1174
  end
2340
1175
  class Fk < ActiveRecord::Base
2341
1176
  declare_schema { }
2342
- belongs_to :id_default, ({})
2343
- belongs_to :id4, ({})
2344
- belongs_to :id8, ({})
1177
+ belongs_to :id_default
1178
+ belongs_to :id4
1179
+ belongs_to :id8
2345
1180
  end
2346
1181
  end
2347
1182