schema_plus 1.5.3 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +8 -8
- data/CHANGELOG.md +10 -4
- data/README.md +24 -4
- data/Rakefile +1 -1
- data/gemfiles/rails-4.1/Gemfile.base +1 -1
- data/lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb +11 -5
- data/lib/schema_plus/active_record/connection_adapters/postgresql_adapter.rb +58 -2
- data/lib/schema_plus/active_record/schema_dumper.rb +10 -0
- data/lib/schema_plus/version.rb +1 -1
- data/runspecs +1 -1
- data/spec/column_default_spec.rb +20 -26
- data/spec/column_spec.rb +22 -24
- data/spec/connections/postgresql/connection.rb +1 -1
- data/spec/enum_spec.rb +132 -0
- data/spec/foreign_key_spec.rb +18 -15
- data/spec/index_definition_spec.rb +97 -102
- data/spec/index_spec.rb +5 -8
- data/spec/migration_spec.rb +288 -303
- data/spec/named_schemas_spec.rb +24 -26
- data/spec/schema_dumper_spec.rb +66 -53
- data/spec/spec_helper.rb +6 -0
- data/spec/views_spec.rb +41 -24
- metadata +24 -22
data/spec/migration_spec.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
3
|
|
4
4
|
describe ActiveRecord::Migration do
|
5
|
-
include SchemaPlusHelpers
|
6
5
|
|
7
6
|
before(:each) do
|
8
7
|
define_schema(:auto_create => true) do
|
@@ -44,7 +43,7 @@ describe ActiveRecord::Migration do
|
|
44
43
|
it "should properly handle default values for booleans" do
|
45
44
|
expect {
|
46
45
|
recreate_table(@model) do |t|
|
47
|
-
|
46
|
+
t.boolean :bool, :default => true
|
48
47
|
end
|
49
48
|
}.to_not raise_error
|
50
49
|
expect(@model.create.reload.bool).to be true
|
@@ -218,15 +217,13 @@ describe ActiveRecord::Migration do
|
|
218
217
|
end
|
219
218
|
end
|
220
219
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
t.string :bar, :index => { :with => :foo, :length => { :foo => 8, :bar => 12 }}
|
226
|
-
end
|
227
|
-
index = @model.indexes.first
|
228
|
-
expect(Hash[index.columns.zip(index.lengths.map(&:to_i))]).to eq({ "foo" => 8, "bar" => 12})
|
220
|
+
it "should pass index length option properly", :mysql => :only do
|
221
|
+
recreate_table(@model) do |t|
|
222
|
+
t.string :foo
|
223
|
+
t.string :bar, :index => { :with => :foo, :length => { :foo => 8, :bar => 12 }}
|
229
224
|
end
|
225
|
+
index = @model.indexes.first
|
226
|
+
expect(Hash[index.columns.zip(index.lengths.map(&:to_i))]).to eq({ "foo" => 8, "bar" => 12})
|
230
227
|
end
|
231
228
|
|
232
229
|
it "should create an index if specified explicitly" do
|
@@ -293,63 +290,69 @@ describe ActiveRecord::Migration do
|
|
293
290
|
|
294
291
|
actions = [:cascade, :restrict, :set_null, :set_default, :no_action]
|
295
292
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
}.to raise_error(NotImplementedError)
|
304
|
-
end
|
305
|
-
|
306
|
-
it "should raise a not-implemented error for on_delete => :set_default" do
|
307
|
-
expect {
|
308
|
-
recreate_table @model do |t|
|
309
|
-
t.integer :user_id, :foreign_key => { :on_delete => :set_default }
|
310
|
-
end
|
311
|
-
}.to raise_error(NotImplementedError)
|
293
|
+
actions.each do |action|
|
294
|
+
if action == :set_default
|
295
|
+
if_action_supported = { :mysql => :skip }
|
296
|
+
if_action_unsupported = { :mysql => :only }
|
297
|
+
else
|
298
|
+
if_action_supported = { :if => true }
|
299
|
+
if_action_unsupported = { :if => false }
|
312
300
|
end
|
313
|
-
end
|
314
301
|
|
315
|
-
|
316
|
-
it "should create and detect on_update #{action.inspect}" do
|
302
|
+
it "should create and detect on_update #{action.inspect}", if_action_supported do
|
317
303
|
recreate_table @model do |t|
|
318
304
|
t.integer :user_id, :foreign_key => { :on_update => action }
|
319
305
|
end
|
320
306
|
expect(@model).to reference.on(:user_id).on_update(action)
|
321
307
|
end
|
322
308
|
|
323
|
-
it "should create and detect on_update #{action.inspect} using shortcut" do
|
309
|
+
it "should create and detect on_update #{action.inspect} using shortcut", if_action_supported do
|
324
310
|
recreate_table @model do |t|
|
325
311
|
t.integer :user_id, :on_update => action
|
326
312
|
end
|
327
313
|
expect(@model).to reference.on(:user_id).on_update(action)
|
328
314
|
end
|
329
315
|
|
330
|
-
it "should
|
316
|
+
it "should raise a not-implemented error for on_update => #{action}", if_action_unsupported do
|
317
|
+
expect {
|
318
|
+
recreate_table @model do |t|
|
319
|
+
t.integer :user_id, :foreign_key => { :on_update => action }
|
320
|
+
end
|
321
|
+
}.to raise_error(NotImplementedError)
|
322
|
+
end
|
323
|
+
|
324
|
+
it "should create and detect on_delete #{action.inspect}", if_action_supported do
|
331
325
|
recreate_table @model do |t|
|
332
326
|
t.integer :user_id, :foreign_key => { :on_delete => action }
|
333
327
|
end
|
334
328
|
expect(@model).to reference.on(:user_id).on_delete(action)
|
335
329
|
end
|
336
330
|
|
337
|
-
it "should create and detect on_delete #{action.inspect} using shortcut" do
|
331
|
+
it "should create and detect on_delete #{action.inspect} using shortcut", if_action_supported do
|
338
332
|
recreate_table @model do |t|
|
339
333
|
t.integer :user_id, :on_delete => action
|
340
334
|
end
|
341
335
|
expect(@model).to reference.on(:user_id).on_delete(action)
|
342
336
|
end
|
337
|
+
|
338
|
+
it "should raise a not-implemented error for on_delete => #{action}", if_action_unsupported do
|
339
|
+
expect {
|
340
|
+
recreate_table @model do |t|
|
341
|
+
t.integer :user_id, :foreign_key => { :on_delete => action }
|
342
|
+
end
|
343
|
+
}.to raise_error(NotImplementedError)
|
344
|
+
end
|
345
|
+
|
343
346
|
end
|
344
347
|
|
345
348
|
[false, true, :initially_deferred].each do |status|
|
346
|
-
it "should create and detect deferrable #{status.inspect}" do
|
349
|
+
it "should create and detect deferrable #{status.inspect}", :mysql => :skip do
|
347
350
|
recreate_table @model do |t|
|
348
351
|
t.integer :user_id, :on_delete => :cascade, :deferrable => status
|
349
352
|
end
|
350
353
|
expect(@model).to reference.on(:user_id).deferrable(status)
|
351
354
|
end
|
352
|
-
end
|
355
|
+
end
|
353
356
|
|
354
357
|
it "should use default on_delete action" do
|
355
358
|
with_fk_config(:on_delete => :cascade) do
|
@@ -407,30 +410,27 @@ describe ActiveRecord::Migration do
|
|
407
410
|
it "should raise an error for an invalid on_delete action" do
|
408
411
|
expect {
|
409
412
|
recreate_table @model do |t|
|
410
|
-
|
413
|
+
t.integer :user_id, :foreign_key => { :on_delete => :invalid }
|
411
414
|
end
|
412
415
|
}.to raise_error(ArgumentError)
|
413
416
|
end
|
414
417
|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
t.integer :user_id
|
420
|
-
end
|
421
|
-
expect(@model).not_to have_index.on(:user_id)
|
418
|
+
it "should override foreign key auto_index negatively", :mysql => :skip do
|
419
|
+
with_fk_config(:auto_index => true) do
|
420
|
+
recreate_table @model, :foreign_keys => {:auto_index => false} do |t|
|
421
|
+
t.integer :user_id
|
422
422
|
end
|
423
|
+
expect(@model).not_to have_index.on(:user_id)
|
423
424
|
end
|
425
|
+
end
|
424
426
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
end
|
430
|
-
expect(@model).not_to have_index.on(:user_id)
|
427
|
+
it "should disable auto-index for a column", :mysql => :skip do
|
428
|
+
with_fk_config(:auto_index => true) do
|
429
|
+
recreate_table @model do |t|
|
430
|
+
t.integer :user_id, :index => false
|
431
431
|
end
|
432
|
+
expect(@model).not_to have_index.on(:user_id)
|
432
433
|
end
|
433
|
-
|
434
434
|
end
|
435
435
|
|
436
436
|
end
|
@@ -449,323 +449,313 @@ describe ActiveRecord::Migration do
|
|
449
449
|
expect(@model).to have_index.on(:state)
|
450
450
|
end
|
451
451
|
|
452
|
-
|
452
|
+
it "should create a foreign key constraint"+suffix, :sqlite3 => :skip do
|
453
|
+
change_table(@model, :bulk => bulk) do |t|
|
454
|
+
t.integer :user_id
|
455
|
+
end
|
456
|
+
expect(@model).to reference(:users, :id).on(:user_id)
|
457
|
+
end
|
453
458
|
|
454
|
-
|
455
|
-
|
456
|
-
|
459
|
+
context "migrate down" do
|
460
|
+
it "should remove a foreign key constraint"+suffix, :sqlite3 => :skip do
|
461
|
+
Comment.reset_column_information
|
462
|
+
expect(Comment).to reference(:users, :id).on(:user_id)
|
463
|
+
migration = Class.new ::ActiveRecord::Migration do
|
464
|
+
define_method(:change) {
|
465
|
+
change_table("comments", :bulk => bulk) do |t|
|
466
|
+
t.integer :user_id
|
467
|
+
end
|
468
|
+
}
|
457
469
|
end
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
context "migrate down" do
|
462
|
-
it "should remove a foreign key constraint"+suffix do
|
463
|
-
Comment.reset_column_information
|
464
|
-
expect(Comment).to reference(:users, :id).on(:user_id)
|
465
|
-
migration = Class.new ::ActiveRecord::Migration do
|
466
|
-
define_method(:change) {
|
467
|
-
change_table("comments", :bulk => bulk) do |t|
|
468
|
-
t.integer :user_id
|
469
|
-
end
|
470
|
-
}
|
471
|
-
end
|
472
|
-
ActiveRecord::Migration.suppress_messages do
|
473
|
-
migration.migrate(:down)
|
474
|
-
end
|
475
|
-
Comment.reset_column_information
|
476
|
-
expect(Comment).not_to reference(:users, :id).on(:user_id)
|
470
|
+
ActiveRecord::Migration.suppress_messages do
|
471
|
+
migration.migrate(:down)
|
477
472
|
end
|
478
|
-
|
473
|
+
Comment.reset_column_information
|
474
|
+
expect(Comment).not_to reference(:users, :id).on(:user_id)
|
475
|
+
end
|
476
|
+
end if ActiveRecord::VERSION::MAJOR >= 4
|
479
477
|
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
end
|
484
|
-
expect(@model).to reference(:users, :id).on(:user_id)
|
478
|
+
it "should create a foreign key constraint using :references"+suffix, :sqlite3 => :skip do
|
479
|
+
change_table(@model, :bulk => bulk) do |t|
|
480
|
+
t.references :user
|
485
481
|
end
|
482
|
+
expect(@model).to reference(:users, :id).on(:user_id)
|
483
|
+
end
|
486
484
|
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
end
|
491
|
-
expect(@model).to reference(:users, :id).on(:user_id)
|
485
|
+
it "should create a foreign key constraint using :belongs_to"+suffix, :sqlite3 => :skip do
|
486
|
+
change_table(@model, :bulk => bulk) do |t|
|
487
|
+
t.belongs_to :user
|
492
488
|
end
|
489
|
+
expect(@model).to reference(:users, :id).on(:user_id)
|
493
490
|
end
|
494
491
|
end
|
495
492
|
end
|
496
493
|
|
494
|
+
context "when column is added", :sqlite3 => :skip do
|
497
495
|
|
498
|
-
|
499
|
-
|
500
|
-
|
496
|
+
before(:each) do
|
497
|
+
@model = Comment
|
498
|
+
end
|
501
499
|
|
502
|
-
|
503
|
-
|
500
|
+
it "should create an index" do
|
501
|
+
add_column(:slug, :string, :index => true) do
|
502
|
+
expect(@model).to have_index.on(:slug)
|
504
503
|
end
|
504
|
+
end
|
505
505
|
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
end
|
506
|
+
it "should create foreign key" do
|
507
|
+
add_column(:post_id, :integer) do
|
508
|
+
expect(@model).to reference(:posts, :id).on(:post_id)
|
510
509
|
end
|
510
|
+
end
|
511
511
|
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
end
|
512
|
+
it "should create foreign key to explicitly given table" do
|
513
|
+
add_column(:author_id, :integer, :foreign_key => { :references => :users }) do
|
514
|
+
expect(@model).to reference(:users, :id).on(:author_id)
|
516
515
|
end
|
516
|
+
end
|
517
517
|
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
end
|
518
|
+
it "should create foreign key to explicitly given table using shortcut" do
|
519
|
+
add_column(:author_id, :integer, :references => :users) do
|
520
|
+
expect(@model).to reference(:users, :id).on(:author_id)
|
522
521
|
end
|
522
|
+
end
|
523
523
|
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
end
|
524
|
+
it "should create foreign key to explicitly given table and column name" do
|
525
|
+
add_column(:author_login, :string, :foreign_key => { :references => [:users, :login]}) do
|
526
|
+
expect(@model).to reference(:users, :login).on(:author_login)
|
528
527
|
end
|
528
|
+
end
|
529
529
|
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
end
|
530
|
+
it "should create foreign key to the same table on parent_id" do
|
531
|
+
add_column(:parent_id, :integer) do
|
532
|
+
expect(@model).to reference(@model.table_name, :id).on(:parent_id)
|
534
533
|
end
|
534
|
+
end
|
535
535
|
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
end
|
536
|
+
it "shouldn't create foreign key if column doesn't look like foreign key" do
|
537
|
+
add_column(:views_count, :integer) do
|
538
|
+
expect(@model).not_to reference.on(:views_count)
|
540
539
|
end
|
540
|
+
end
|
541
541
|
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
end
|
542
|
+
it "shouldn't create foreign key if specified explicitly" do
|
543
|
+
add_column(:post_id, :integer, :foreign_key => false) do
|
544
|
+
expect(@model).not_to reference.on(:post_id)
|
546
545
|
end
|
546
|
+
end
|
547
547
|
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
end
|
548
|
+
it "shouldn't create foreign key if specified explicitly by shorthand" do
|
549
|
+
add_column(:post_id, :integer, :references => nil) do
|
550
|
+
expect(@model).not_to reference.on(:post_id)
|
552
551
|
end
|
552
|
+
end
|
553
553
|
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
end
|
554
|
+
it "should create an index if specified" do
|
555
|
+
add_column(:post_id, :integer, :index => true) do
|
556
|
+
expect(@model).to have_index.on(:post_id)
|
558
557
|
end
|
558
|
+
end
|
559
559
|
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
end
|
560
|
+
it "should create a unique index if specified" do
|
561
|
+
add_column(:post_id, :integer, :index => { :unique => true }) do
|
562
|
+
expect(@model).to have_unique_index.on(:post_id)
|
564
563
|
end
|
564
|
+
end
|
565
565
|
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
end
|
566
|
+
it "should create a unique index if specified by shorthand" do
|
567
|
+
add_column(:post_id, :integer, :index => :unique) do
|
568
|
+
expect(@model).to have_unique_index.on(:post_id)
|
570
569
|
end
|
570
|
+
end
|
571
571
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
572
|
+
it "should allow custom name for index" do
|
573
|
+
index_name = 'comments_post_id_unique_index'
|
574
|
+
add_column(:post_id, :integer, :index => { :unique => true, :name => index_name }) do
|
575
|
+
expect(@model).to have_unique_index(:name => index_name).on(:post_id)
|
576
576
|
end
|
577
|
+
end
|
577
578
|
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
end
|
579
|
+
it "should auto-index if specified in global options" do
|
580
|
+
SchemaPlus.config.foreign_keys.auto_index = true
|
581
|
+
add_column(:post_id, :integer) do
|
582
|
+
expect(@model).to have_index.on(:post_id)
|
583
583
|
end
|
584
|
+
SchemaPlus.config.foreign_keys.auto_index = false
|
585
|
+
end
|
584
586
|
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
end
|
590
|
-
SchemaPlus.config.foreign_keys.auto_index = false
|
587
|
+
it "should auto-index foreign keys only" do
|
588
|
+
SchemaPlus.config.foreign_keys.auto_index = true
|
589
|
+
add_column(:state, :integer) do
|
590
|
+
expect(@model).not_to have_index.on(:state)
|
591
591
|
end
|
592
|
+
SchemaPlus.config.foreign_keys.auto_index = false
|
593
|
+
end
|
592
594
|
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
SchemaPlus.config.foreign_keys.auto_index = false
|
595
|
+
# MySQL creates an index on foreign key and we can't override that
|
596
|
+
it "should allow to overwrite auto_index options in column definition", :mysql => :skip do
|
597
|
+
SchemaPlus.config.foreign_keys.auto_index = true
|
598
|
+
add_column(:post_id, :integer, :index => false) do
|
599
|
+
expect(@model).not_to have_index.on(:post_id)
|
599
600
|
end
|
601
|
+
SchemaPlus.config.foreign_keys.auto_index = false
|
602
|
+
end
|
600
603
|
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
# and we can do nothing with that
|
606
|
-
unless SchemaPlusHelpers.mysql?
|
607
|
-
expect(@model).not_to have_index.on(:post_id)
|
608
|
-
end
|
609
|
-
end
|
610
|
-
SchemaPlus.config.foreign_keys.auto_index = false
|
604
|
+
it "should use default on_update action" do
|
605
|
+
SchemaPlus.config.foreign_keys.on_update = :cascade
|
606
|
+
add_column(:post_id, :integer) do
|
607
|
+
expect(@model).to reference.on(:post_id).on_update(:cascade)
|
611
608
|
end
|
609
|
+
SchemaPlus.config.foreign_keys.on_update = nil
|
610
|
+
end
|
612
611
|
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
end
|
618
|
-
SchemaPlus.config.foreign_keys.on_update = nil
|
612
|
+
it "should use default on_delete action" do
|
613
|
+
SchemaPlus.config.foreign_keys.on_delete = :cascade
|
614
|
+
add_column(:post_id, :integer) do
|
615
|
+
expect(@model).to reference.on(:post_id).on_delete(:cascade)
|
619
616
|
end
|
617
|
+
SchemaPlus.config.foreign_keys.on_delete = nil
|
618
|
+
end
|
620
619
|
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
SchemaPlus.config.foreign_keys.on_delete = nil
|
620
|
+
it "should allow to overwrite default actions" do
|
621
|
+
SchemaPlus.config.foreign_keys.on_delete = :cascade
|
622
|
+
SchemaPlus.config.foreign_keys.on_update = :restrict
|
623
|
+
add_column(:post_id, :integer, :foreign_key => { :on_update => :set_null, :on_delete => :set_null}) do
|
624
|
+
expect(@model).to reference.on(:post_id).on_delete(:set_null).on_update(:set_null)
|
627
625
|
end
|
626
|
+
SchemaPlus.config.foreign_keys.on_delete = nil
|
627
|
+
end
|
628
628
|
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
629
|
+
protected
|
630
|
+
def add_column(column_name, *args)
|
631
|
+
table = @model.table_name
|
632
|
+
ActiveRecord::Migration.suppress_messages do
|
633
|
+
ActiveRecord::Migration.add_column(table, column_name, *args)
|
634
|
+
@model.reset_column_information
|
635
|
+
yield if block_given?
|
636
|
+
ActiveRecord::Migration.remove_column(table, column_name)
|
636
637
|
end
|
638
|
+
end
|
637
639
|
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
ActiveRecord::Migration.add_column(table, column_name, *args)
|
643
|
-
@model.reset_column_information
|
644
|
-
yield if block_given?
|
645
|
-
ActiveRecord::Migration.remove_column(table, column_name)
|
646
|
-
end
|
647
|
-
end
|
640
|
+
end
|
641
|
+
|
642
|
+
|
643
|
+
context "when column is changed", :sqlite3 => :skip do
|
648
644
|
|
645
|
+
before(:each) do
|
646
|
+
@model = Comment
|
649
647
|
end
|
650
648
|
|
649
|
+
it "should create foreign key" do
|
650
|
+
change_column :user, :string, :foreign_key => { :references => [:users, :login] }
|
651
|
+
expect(@model).to reference(:users, :login).on(:user)
|
652
|
+
end
|
651
653
|
|
652
|
-
context "
|
654
|
+
context "and initially references to users table" do
|
653
655
|
|
654
656
|
before(:each) do
|
655
|
-
@model
|
657
|
+
recreate_table @model do |t|
|
658
|
+
t.integer :user_id
|
659
|
+
end
|
656
660
|
end
|
657
661
|
|
658
|
-
it "should
|
659
|
-
|
660
|
-
expect(@model).to reference(:users, :login).on(:user)
|
662
|
+
it "should have foreign key" do
|
663
|
+
expect(@model).to reference(:users)
|
661
664
|
end
|
662
665
|
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
t.integer :user_id
|
668
|
-
end
|
669
|
-
end
|
670
|
-
|
671
|
-
it "should have foreign key" do
|
672
|
-
expect(@model).to reference(:users)
|
673
|
-
end
|
666
|
+
it "should drop foreign key if it is no longer valid" do
|
667
|
+
change_column :user_id, :integer, :foreign_key => { :references => :members }
|
668
|
+
expect(@model).not_to reference(:users)
|
669
|
+
end
|
674
670
|
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
671
|
+
it "should drop foreign key if requested to do so" do
|
672
|
+
change_column :user_id, :integer, :foreign_key => { :references => nil }
|
673
|
+
expect(@model).not_to reference(:users)
|
674
|
+
end
|
679
675
|
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
676
|
+
it "should remove auto-created index if foreign key is removed" do
|
677
|
+
expect(@model).to have_index.on(:user_id) # sanity check that index was auto-created
|
678
|
+
change_column :user_id, :integer, :foreign_key => { :references => nil }
|
679
|
+
expect(@model).not_to have_index.on(:user_id)
|
680
|
+
end
|
684
681
|
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
end
|
682
|
+
it "should reference pointed table afterwards if new one is created" do
|
683
|
+
change_column :user_id, :integer, :foreign_key => { :references => :members }
|
684
|
+
expect(@model).to reference(:members)
|
685
|
+
end
|
690
686
|
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
687
|
+
it "should maintain foreign key if it's unaffected by change" do
|
688
|
+
change_column :user_id, :integer, :default => 0
|
689
|
+
expect(@model).to reference(:users)
|
690
|
+
end
|
695
691
|
|
696
|
-
|
692
|
+
it "should maintain foreign key if it's unaffected by change, even if auto_index is off" do
|
693
|
+
with_fk_config(:auto_create => false) do
|
697
694
|
change_column :user_id, :integer, :default => 0
|
698
695
|
expect(@model).to reference(:users)
|
699
696
|
end
|
700
|
-
|
701
|
-
it "should maintain foreign key if it's unaffected by change, even if auto_index is off" do
|
702
|
-
with_fk_config(:auto_create => false) do
|
703
|
-
change_column :user_id, :integer, :default => 0
|
704
|
-
expect(@model).to reference(:users)
|
705
|
-
end
|
706
|
-
end
|
707
|
-
|
708
697
|
end
|
709
698
|
|
710
|
-
|
711
|
-
before(:each) do
|
712
|
-
recreate_table @model do |t|
|
713
|
-
t.integer :user_id, :foreign_key => false, :index => true
|
714
|
-
end
|
715
|
-
end
|
716
|
-
|
717
|
-
it "should create the index" do
|
718
|
-
expect(@model).to have_index.on(:user_id)
|
719
|
-
end
|
699
|
+
end
|
720
700
|
|
721
|
-
|
722
|
-
|
701
|
+
context "if column defined without foreign key but with index" do
|
702
|
+
before(:each) do
|
703
|
+
recreate_table @model do |t|
|
704
|
+
t.integer :user_id, :foreign_key => false, :index => true
|
723
705
|
end
|
724
706
|
end
|
725
707
|
|
726
|
-
|
727
|
-
|
728
|
-
table = @model.table_name
|
729
|
-
ActiveRecord::Migration.suppress_messages do
|
730
|
-
ActiveRecord::Migration.change_column(table, column_name, *args)
|
731
|
-
@model.reset_column_information
|
732
|
-
end
|
708
|
+
it "should create the index" do
|
709
|
+
expect(@model).to have_index.on(:user_id)
|
733
710
|
end
|
734
711
|
|
712
|
+
it "adding foreign key should not fail due to attempt to auto-create existing index" do
|
713
|
+
expect { change_column :user_id, :integer, :foreign_key => true }.to_not raise_error
|
714
|
+
end
|
735
715
|
end
|
736
716
|
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
717
|
+
protected
|
718
|
+
def change_column(column_name, *args)
|
719
|
+
table = @model.table_name
|
720
|
+
ActiveRecord::Migration.suppress_messages do
|
721
|
+
ActiveRecord::Migration.change_column(table, column_name, *args)
|
722
|
+
@model.reset_column_information
|
743
723
|
end
|
724
|
+
end
|
744
725
|
|
745
|
-
|
746
|
-
expect(@model).to reference(:posts)
|
747
|
-
remove_column(:post_id)
|
748
|
-
expect(@model).not_to reference(:posts)
|
749
|
-
end
|
726
|
+
end
|
750
727
|
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
728
|
+
context "when column is removed", :sqlite3 => :skip do
|
729
|
+
before(:each) do
|
730
|
+
@model = Comment
|
731
|
+
recreate_table @model do |t|
|
732
|
+
t.integer :post_id
|
755
733
|
end
|
734
|
+
end
|
756
735
|
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
736
|
+
it "should remove a foreign key" do
|
737
|
+
expect(@model).to reference(:posts)
|
738
|
+
remove_column(:post_id)
|
739
|
+
expect(@model).not_to reference(:posts)
|
740
|
+
end
|
741
|
+
|
742
|
+
it "should remove an index" do
|
743
|
+
expect(@model).to have_index.on(:post_id)
|
744
|
+
remove_column(:post_id)
|
745
|
+
expect(@model).not_to have_index.on(:post_id)
|
765
746
|
end
|
766
747
|
|
748
|
+
protected
|
749
|
+
def remove_column(column_name)
|
750
|
+
table = @model.table_name
|
751
|
+
ActiveRecord::Migration.suppress_messages do
|
752
|
+
ActiveRecord::Migration.remove_column(table, column_name)
|
753
|
+
@model.reset_column_information
|
754
|
+
end
|
755
|
+
end
|
767
756
|
end
|
768
757
|
|
758
|
+
|
769
759
|
context "when table is renamed" do
|
770
760
|
|
771
761
|
before(:each) do
|
@@ -799,44 +789,39 @@ describe ActiveRecord::Migration do
|
|
799
789
|
expect(index.name).to match(/^fk__newname_/)
|
800
790
|
end
|
801
791
|
|
802
|
-
|
803
|
-
|
804
|
-
expect(ActiveRecord::Base.connection.foreign_keys(:newname).first.name).to match(/newname/)
|
805
|
-
end
|
792
|
+
it "should rename foreign key constraints", :sqlite3 => :skip do
|
793
|
+
expect(ActiveRecord::Base.connection.foreign_keys(:newname).first.name).to match(/newname/)
|
806
794
|
end
|
807
795
|
|
808
796
|
end
|
809
797
|
|
810
|
-
unless SchemaPlusHelpers.sqlite3?
|
811
798
|
|
812
|
-
|
799
|
+
context "when table with more than one fk constraint is renamed", :sqlite3 => :skip do
|
813
800
|
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
end
|
801
|
+
before(:each) do
|
802
|
+
@model = Comment
|
803
|
+
recreate_table @model do |t|
|
804
|
+
t.integer :user_id
|
805
|
+
t.integer :member_id
|
806
|
+
end
|
807
|
+
ActiveRecord::Migration.suppress_messages do
|
808
|
+
ActiveRecord::Migration.rename_table @model.table_name, :newname
|
823
809
|
end
|
810
|
+
end
|
824
811
|
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
end
|
812
|
+
around(:each) do |example|
|
813
|
+
begin
|
814
|
+
example.run
|
815
|
+
ensure
|
816
|
+
ActiveRecord::Migration.suppress_messages do
|
817
|
+
ActiveRecord::Migration.rename_table :newname, :comments
|
832
818
|
end
|
833
819
|
end
|
834
|
-
it "should rename foreign key constraints" do
|
835
|
-
names = ActiveRecord::Base.connection.foreign_keys(:newname).map(&:name)
|
836
|
-
expect(names.grep(/newname/)).to eq(names)
|
837
|
-
end
|
838
820
|
end
|
839
|
-
|
821
|
+
it "should rename foreign key constraints" do
|
822
|
+
names = ActiveRecord::Base.connection.foreign_keys(:newname).map(&:name)
|
823
|
+
expect(names.grep(/newname/)).to eq(names)
|
824
|
+
end
|
840
825
|
end
|
841
826
|
|
842
827
|
def recreate_table(model, opts={}, &block)
|