declare_schema 1.3.6 → 1.4.0.colin.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -108,8 +108,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
108
108
  add_column :adverts, :published_at, :datetime, null: true
109
109
  EOS
110
110
  .and migrate_down(<<~EOS.strip)
111
- remove_column :adverts, :published_at
112
- remove_column :adverts, :body
111
+ remove_column :adverts, :published_at
112
+ remove_column :adverts, :body
113
113
  EOS
114
114
  )
115
115
 
@@ -141,8 +141,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
141
141
  remove_column :adverts, :name
142
142
  EOS
143
143
  .and migrate_down(<<~EOS.strip)
144
- add_column :adverts, :name, :string, limit: 250, null: true#{charset_and_collation}
145
- remove_column :adverts, :title
144
+ add_column :adverts, :name, :string, limit: 250, null: true#{charset_and_collation}
145
+ remove_column :adverts, :title
146
146
  EOS
147
147
  )
148
148
 
@@ -179,7 +179,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
179
179
  change_column :adverts, :title, :string, limit: 250, null: true, default: "Untitled"#{charset_and_collation}
180
180
  EOS
181
181
  .and migrate_down(<<~EOS.strip)
182
- change_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
182
+ change_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
183
183
  EOS
184
184
  )
185
185
 
@@ -209,7 +209,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
209
209
  change_column :adverts, :price, :integer, limit: 3, null: true
210
210
  EOS
211
211
  .and migrate_down(<<~EOS.strip)
212
- change_column :adverts, :price, :integer, limit: 2, null: true
212
+ change_column :adverts, :price, :integer, limit: 2, null: true
213
213
  EOS
214
214
  )
215
215
 
@@ -306,7 +306,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
306
306
  change_column :adverts, :description, :text, limit: 4294967295, null: false#{charset_and_collation}
307
307
  EOS
308
308
  .and migrate_down(<<~EOS.strip)
309
- change_column :adverts, :description, :text#{', limit: 255' if defined?(Mysql2)}, null: true#{charset_and_collation}
309
+ change_column :adverts, :description, :text#{', limit: 255' if defined?(Mysql2)}, null: true#{charset_and_collation}
310
310
  EOS
311
311
  )
312
312
 
@@ -323,7 +323,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
323
323
  change_column :adverts, :description, :text, limit: 4294967295, null: false#{charset_and_collation}
324
324
  EOS
325
325
  .and migrate_down(<<~EOS.strip)
326
- change_column :adverts, :description, :text#{', limit: 255' if defined?(Mysql2)}, null: true#{charset_and_collation}
326
+ change_column :adverts, :description, :text#{', limit: 255' if defined?(Mysql2)}, null: true#{charset_and_collation}
327
327
  EOS
328
328
  )
329
329
  end
@@ -363,14 +363,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
363
363
  #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" if defined?(Mysql2)}
364
364
  EOS
365
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: :index_adverts_on_category_id
368
- remove_column :adverts, :category_id
366
+ #{"remove_foreign_key :adverts, name: :index_adverts_on_category_id" if defined?(Mysql2)}
367
+ remove_index :adverts, name: :index_adverts_on_category_id
368
+ remove_column :adverts, :category_id
369
369
  EOS
370
370
  )
371
371
 
372
372
  Advert.field_specs.delete(:category_id)
373
- Advert.index_definitions.delete_if { |spec| spec.fields==["category_id"] }
373
+ Advert.index_definitions.delete_if { |spec| spec.fields == ["category_id"] }
374
374
 
375
375
  # If you specify a custom foreign key, the migration generator observes that:
376
376
 
@@ -411,7 +411,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
411
411
  Advert.field_specs.delete(:category_id)
412
412
  Advert.index_definitions.delete_if { |spec| spec.fields == ["category_id"] }
413
413
 
414
- # You can specify the index name with :index
414
+ # You can specify the index name with index: 'name' [deprecated]
415
+
416
+ expect(Kernel).to receive(:warn).with(/belongs_to index: 'name' is deprecated; use index: \{ name: 'name' \} instead/i)
415
417
 
416
418
  class Category < ActiveRecord::Base; end
417
419
  class Advert < ActiveRecord::Base
@@ -431,6 +433,26 @@ RSpec.describe 'DeclareSchema Migration Generator' do
431
433
  Advert.field_specs.delete(:category_id)
432
434
  Advert.index_definitions.delete_if { |spec| spec.fields == ["category_id"] }
433
435
 
436
+ # You can specify the index name with index: { name: }'name', unique: true|false }
437
+
438
+ class Category < ActiveRecord::Base; end
439
+ class Advert < ActiveRecord::Base
440
+ declare_schema { }
441
+ belongs_to :category, index: { name: 'my_index', unique: false }
442
+ end
443
+
444
+ expect(Generators::DeclareSchema::Migration::Migrator.run).to(
445
+ migrate_up(<<~EOS.strip)
446
+ add_column :adverts, :category_id, :integer, limit: 8, null: false
447
+ add_index :adverts, [:category_id], name: :my_index
448
+ #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
449
+ "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
450
+ EOS
451
+ )
452
+
453
+ Advert.field_specs.delete(:category_id)
454
+ Advert.index_definitions.delete_if { |spec| spec.fields == ["category_id"] }
455
+
434
456
  ### Timestamps and Optimimistic Locking
435
457
 
436
458
  # `updated_at` and `created_at` can be declared with the shorthand `timestamps`.
@@ -452,11 +474,11 @@ RSpec.describe 'DeclareSchema Migration Generator' do
452
474
  "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
453
475
  EOS
454
476
  .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
477
+ #{"remove_foreign_key :adverts, name: :index_adverts_on_c_id\n" +
478
+ "remove_foreign_key :adverts, name: :index_adverts_on_category_id" if defined?(Mysql2)}
479
+ remove_column :adverts, :lock_version
480
+ remove_column :adverts, :updated_at
481
+ remove_column :adverts, :created_at
460
482
  EOS
461
483
  )
462
484
 
@@ -468,22 +490,29 @@ RSpec.describe 'DeclareSchema Migration Generator' do
468
490
 
469
491
  # You can add an index to a field definition
470
492
 
493
+ expect(Kernel).to receive(:warn).with(/belongs_to index: 'name' is deprecated; use index: \{ name: 'name' \} instead/i)
494
+ expect(Kernel).to receive(:warn).with(/belongs_to unique: true\|false is deprecated; use index: \{ unique: true\|false \} instead/i)
495
+
471
496
  class Advert < ActiveRecord::Base
472
497
  declare_schema do
473
498
  string :title, index: true, limit: 250, null: true
474
499
  end
500
+ belongs_to :category, index: 'my_index', unique: false
475
501
  end
476
502
 
477
503
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
478
504
  migrate_up(<<~EOS.strip)
479
505
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
506
+ add_column :adverts, :category_id, :integer, limit: 8, null: false
480
507
  add_index :adverts, [:title], name: :index_adverts_on_title
508
+ add_index :adverts, [:category_id], name: :my_index
481
509
  #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
482
510
  "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
483
511
  EOS
484
512
  )
485
513
 
486
- Advert.index_definitions.delete_if { |spec| spec.fields==["title"] }
514
+ Advert.field_specs.delete(:category_id)
515
+ Advert.index_definitions.delete_if { |spec| spec.fields == ["title"] || spec.fields == ["category_id"] }
487
516
 
488
517
  # You can ask for a unique index
489
518
 
@@ -521,7 +550,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
521
550
  EOS
522
551
  )
523
552
 
524
- Advert.index_definitions.delete_if { |spec| spec.fields==["title"] }
553
+ Advert.index_definitions.delete_if { |spec| spec.fields == ["title"] }
525
554
 
526
555
  # You can ask for an index outside of the fields block
527
556
 
@@ -540,16 +569,16 @@ RSpec.describe 'DeclareSchema Migration Generator' do
540
569
 
541
570
  Advert.index_definitions.delete_if { |spec| spec.fields == ["title"] }
542
571
 
543
- # The available options for the index function are `:unique` and `:name`
572
+ # The available options for the index function are :unique, :name, :where, and :length.
544
573
 
545
574
  class Advert < ActiveRecord::Base
546
- index :title, unique: true, name: 'my_index'
575
+ index :title, unique: false, name: 'my_index', length: 10
547
576
  end
548
577
 
549
578
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
550
579
  migrate_up(<<~EOS.strip)
551
580
  add_column :adverts, :title, :string, limit: 250, null: true#{charset_and_collation}
552
- add_index :adverts, [:title], name: :my_index, unique: true
581
+ add_index :adverts, [:title], name: :my_index, length: 10
553
582
  #{"add_foreign_key :adverts, :categories, column: :category_id, name: :index_adverts_on_category_id\n" +
554
583
  "add_foreign_key :adverts, :categories, column: :c_id, name: :index_adverts_on_c_id" if defined?(Mysql2)}
555
584
  EOS
@@ -572,7 +601,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
572
601
  EOS
573
602
  )
574
603
 
575
- Advert.index_definitions.delete_if { |spec| spec.fields==["title", "category_id"] }
604
+ Advert.index_definitions.delete_if { |spec| spec.fields == ["title", "category_id"] }
576
605
 
577
606
  # Finally, you can specify that the migration generator should completely ignore an
578
607
  # index by passing its name to ignore_index in the model.
@@ -645,10 +674,10 @@ RSpec.describe 'DeclareSchema Migration Generator' do
645
674
  remove_column :advertisements, :name
646
675
  EOS
647
676
  .and migrate_down(<<~EOS.strip)
648
- add_column :advertisements, :name, :string, limit: 250, null: true#{charset_and_collation}
649
- remove_column :advertisements, :body
650
- remove_column :advertisements, :title
651
- rename_table :advertisements, :adverts
677
+ add_column :advertisements, :name, :string, limit: 250, null: true#{charset_and_collation}
678
+ remove_column :advertisements, :body
679
+ remove_column :advertisements, :title
680
+ rename_table :advertisements, :adverts
652
681
  EOS
653
682
  )
654
683
 
@@ -665,9 +694,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
665
694
  drop_table :adverts
666
695
  EOS
667
696
  .and migrate_down(<<~EOS.strip)
668
- create_table "adverts"#{table_options}, force: :cascade do |t|
669
- t.string "name", limit: 250#{charset_and_collation}
670
- end
697
+ create_table "adverts"#{table_options}, force: :cascade do |t|
698
+ t.string "name", limit: 250#{charset_and_collation}
699
+ end
671
700
  EOS
672
701
  )
673
702
 
@@ -700,8 +729,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
700
729
  add_index :adverts, [:type], name: :on_type
701
730
  EOS
702
731
  .and migrate_down(<<~EOS.strip)
703
- remove_index :adverts, name: :on_type
704
- remove_column :adverts, :type
732
+ remove_index :adverts, name: :on_type
733
+ remove_column :adverts, :type
705
734
  EOS
706
735
  )
707
736
  end
@@ -709,7 +738,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
709
738
  Advert.field_specs.delete(:type)
710
739
  nuke_model_class(SuperFancyAdvert)
711
740
  nuke_model_class(FancyAdvert)
712
- Advert.index_definitions.delete_if { |spec| spec.fields==["type"] }
741
+ Advert.index_definitions.delete_if { |spec| spec.fields == ["type"] }
713
742
 
714
743
  ## Coping with multiple changes
715
744
 
@@ -744,8 +773,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
744
773
  change_column :adverts, :name, :string, limit: 250, null: true, default: "No Name"#{charset_and_collation}
745
774
  EOS
746
775
  .and migrate_down(<<~EOS.strip)
747
- change_column :adverts, :name, :string, limit: 250, null: true, default: "Untitled"#{charset_and_collation}
748
- rename_column :adverts, :name, :title
776
+ change_column :adverts, :name, :string, limit: 250, null: true, default: "Untitled"#{charset_and_collation}
777
+ rename_column :adverts, :name, :title
749
778
  EOS
750
779
  )
751
780
 
@@ -809,8 +838,6 @@ RSpec.describe 'DeclareSchema Migration Generator' do
809
838
  expect(User.field_specs.keys).to eq(['company'])
810
839
  expect(User.field_specs['company'].options[:ruby_default]&.call).to eq("BigCorp")
811
840
 
812
- nuke_model_class(User)
813
-
814
841
  ## validates
815
842
 
816
843
  # DeclareSchema can accept a validates hash in the field options.
@@ -831,44 +858,6 @@ RSpec.describe 'DeclareSchema Migration Generator' do
831
858
  up, _down = Generators::DeclareSchema::Migration::Migrator.run
832
859
  ActiveRecord::Migration.class_eval(up)
833
860
  expect(Ad.field_specs['company'].options[:validates].inspect).to eq("{:presence=>true, :uniqueness=>{:case_sensitive=>false}}")
834
-
835
- # DeclareSchema supports has_and_belongs_to_many relationships and generates the intersection ("join") table
836
- # with appropriate primary key, indexes, and foreign keys.
837
-
838
- class Advertiser < ActiveRecord::Base
839
- declare_schema do
840
- string :name, limit: 250
841
- end
842
- has_and_belongs_to_many :creatives
843
- end
844
- class Creative < ActiveRecord::Base
845
- declare_schema do
846
- string :url, limit: 500
847
- end
848
- has_and_belongs_to_many :advertisers
849
- end
850
-
851
- expect(Generators::DeclareSchema::Migration::Migrator.run).to(
852
- migrate_up(<<~EOS.strip)
853
- create_table :advertisers, id: :bigint#{create_table_charset_and_collation} do |t|
854
- t.string :name, limit: 250, null: false#{charset_and_collation}
855
- end
856
- create_table :advertisers_creatives, primary_key: [:advertiser_id, :creative_id]#{create_table_charset_and_collation} do |t|
857
- t.integer :advertiser_id, limit: 8, null: false
858
- t.integer :creative_id, limit: 8, null: false
859
- end
860
- create_table :creatives, id: :bigint#{create_table_charset_and_collation} do |t|
861
- t.string :url, limit: 500, null: false#{charset_and_collation}
862
- end
863
- add_index :advertisers_creatives, [:creative_id], name: :index_advertisers_creatives_on_creative_id
864
- add_foreign_key :advertisers_creatives, :advertisers, column: :advertiser_id, name: :advertisers_creatives_FK1
865
- add_foreign_key :advertisers_creatives, :creatives, column: :creative_id, name: :advertisers_creatives_FK2
866
- EOS
867
- )
868
-
869
- nuke_model_class(Ad)
870
- nuke_model_class(Advertiser)
871
- nuke_model_class(Creative)
872
861
  end
873
862
 
874
863
  context 'models with the same parent foreign key relation' do
@@ -892,24 +881,24 @@ RSpec.describe 'DeclareSchema Migration Generator' do
892
881
  end
893
882
  end
894
883
 
895
- it 'will generate unique constraint names' do
884
+ it 'will genereate unique constraint names' do
896
885
  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
897
886
  migrate_up(<<~EOS.strip)
898
- create_table :categories, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
899
- t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
900
- end
901
- create_table :advertisers, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
902
- t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
903
- t.integer :category_id, limit: 8, null: false
904
- end
905
- create_table :affiliates, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
906
- t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
907
- t.integer :category_id, limit: 8, null: false
908
- end
909
- add_index :advertisers, [:category_id], name: :index_advertisers_on_category_id
910
- add_index :affiliates, [:category_id], name: :index_affiliates_on_category_id
911
- add_foreign_key :advertisers, :categories, column: :category_id, name: :index_advertisers_on_category_id
912
- add_foreign_key :affiliates, :categories, column: :category_id, name: :index_affiliates_on_category_id
887
+ create_table :categories, 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
+ end
890
+ create_table :advertisers, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
891
+ t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
892
+ t.integer :category_id, limit: 8, null: false
893
+ end
894
+ create_table :affiliates, id: :bigint, options: "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin" do |t|
895
+ t.string :name, limit: 250, null: true, charset: "utf8mb4", collation: "utf8mb4_bin"
896
+ t.integer :category_id, limit: 8, null: false
897
+ end
898
+ add_index :advertisers, [:category_id], name: :index_advertisers_on_category_id
899
+ add_index :affiliates, [:category_id], name: :index_affiliates_on_category_id
900
+ add_foreign_key :advertisers, :categories, column: :category_id, name: :index_advertisers_on_category_id
901
+ add_foreign_key :affiliates, :categories, column: :category_id, name: :index_affiliates_on_category_id
913
902
  EOS
914
903
  )
915
904
  migrate
@@ -21,9 +21,9 @@ RSpec.describe DeclareSchema::Model::ForeignKeyDefinition do
21
21
  describe 'instance methods' do
22
22
  let(:connection) { instance_double(ActiveRecord::Base.connection.class) }
23
23
  let(:model) { instance_double('Model', table_name: 'models', connection: connection) }
24
- let(:foreign_key_column) { :network_id }
25
- let(:options) { { child_table: 'networks' } }
26
- subject { described_class.new(foreign_key_column, **options)}
24
+ let(:foreign_key) { :network_id }
25
+ let(:options) { {} }
26
+ subject { described_class.new(model, foreign_key, **options)}
27
27
 
28
28
  before do
29
29
  allow(model.connection).to receive(:index_name).with(any_args) { 'index_on_network_id' }
@@ -31,44 +31,45 @@ RSpec.describe DeclareSchema::Model::ForeignKeyDefinition do
31
31
 
32
32
  describe '#initialize' do
33
33
  it 'normalizes symbols to strings' do
34
- expect(subject.foreign_key_column).to eq('network_id')
34
+ expect(subject.foreign_key).to eq('network_id')
35
35
  expect(subject.parent_table_name).to eq('networks')
36
36
  end
37
37
 
38
38
  context 'when most options passed' do
39
- let(:options) { { child_table: 'networks', parent_table: :networks } }
39
+ let(:options) { { parent_table: :networks, foreign_key: :the_network_id } }
40
40
 
41
41
  it 'normalizes symbols to strings' do
42
- expect(subject.foreign_key_column).to eq('network_id')
42
+ expect(subject.foreign_key).to eq('network_id')
43
+ expect(subject.foreign_key_name).to eq('the_network_id')
43
44
  expect(subject.parent_table_name).to eq('networks')
44
- expect(subject.foreign_key_column).to eq('network_id')
45
- expect(subject.constraint_name).to eq('index_networks_on_network_id')
46
- expect(subject.dependent).to be_nil
45
+ expect(subject.foreign_key).to eq('network_id')
46
+ expect(subject.constraint_name).to eq('index_on_network_id')
47
+ expect(subject.on_delete_cascade).to be_falsey
47
48
  end
48
49
  end
49
50
 
50
51
  context 'when all options passed' do
51
- let(:options) { { child_table: 'networks', parent_table: :networks, constraint_name: :constraint_1, dependent: :delete } }
52
+ let(:options) { { parent_table: :networks, foreign_key: :the_network_id, constraint_name: :constraint_1, dependent: :delete } }
52
53
 
53
54
  it 'normalizes symbols to strings' do
54
- expect(subject.foreign_key_column).to eq('network_id')
55
+ expect(subject.foreign_key).to eq('network_id')
56
+ expect(subject.foreign_key_name).to eq('the_network_id')
55
57
  expect(subject.parent_table_name).to eq('networks')
56
58
  expect(subject.constraint_name).to eq('constraint_1')
57
- expect(subject.dependent).to eq(:delete)
59
+ expect(subject.on_delete_cascade).to be_truthy
58
60
  end
59
61
  end
60
62
 
61
63
  context 'when constraint name passed as empty string' do
62
- let(:options) { { child_table: 'networks', constraint_name: "" } }
63
-
64
+ let(:options) { { constraint_name: "" } }
64
65
  it 'defaults to rails constraint name' do
65
- expect(subject.constraint_name).to eq("index_networks_on_network_id")
66
+ expect(subject.constraint_name).to eq("index_on_network_id")
66
67
  end
67
68
  end
68
69
 
69
70
  context 'when no constraint name passed' do
70
71
  it 'defaults to rails constraint name' do
71
- expect(subject.constraint_name).to eq("index_networks_on_network_id")
72
+ expect(subject.constraint_name).to eq("index_on_network_id")
72
73
  end
73
74
  end
74
75
  end
@@ -84,13 +85,13 @@ RSpec.describe DeclareSchema::Model::ForeignKeyDefinition do
84
85
  allow(connection).to receive(:index_name).with('models', column: 'network_id') { }
85
86
  end
86
87
 
87
- describe '.for_table' do
88
- subject { described_class.for_table(old_table_name, model.connection) }
88
+ describe '.for_model' do
89
+ subject { described_class.for_model(model, old_table_name) }
89
90
 
90
- it 'returns definitions' do
91
- expect(subject.map(&:key)).to eq([
92
- ["networks", "network_id", nil]
93
- ])
91
+ it 'returns new object' do
92
+ expect(subject.size).to eq(1), subject.inspect
93
+ expect(subject.first).to be_kind_of(described_class)
94
+ expect(subject.first.foreign_key).to eq('network_id')
94
95
  end
95
96
  end
96
97
  end
@@ -8,20 +8,19 @@ end
8
8
  require_relative '../../../../lib/declare_schema/model/habtm_model_shim'
9
9
 
10
10
  RSpec.describe DeclareSchema::Model::HabtmModelShim do
11
- let(:join_table) { "customers_users" }
12
- let(:foreign_keys) { ["user_id", "customer_id"] }
13
- let(:parent_table_names) { ["users", "customers"] }
14
- let(:connection) { instance_double(ActiveRecord::Base.connection.class, "connection") }
11
+ let(:join_table) { "parent_1_parent_2" }
12
+ let(:foreign_keys) { ["parent_1_id", "parent_2_id"] }
13
+ let(:foreign_key_classes) { [Parent1, Parent2] }
15
14
 
16
15
  before do
17
16
  load File.expand_path('../prepare_testapp.rb', __dir__)
18
17
 
19
- class User < ActiveRecord::Base
20
- self.table_name = "users"
18
+ class Parent1 < ActiveRecord::Base
19
+ self.table_name = "parent_1s"
21
20
  end
22
21
 
23
- class Customer < ActiveRecord::Base
24
- self.table_name = "customers"
22
+ class Parent2 < ActiveRecord::Base
23
+ self.table_name = "parent_2s"
25
24
  end
26
25
  end
27
26
 
@@ -30,26 +29,27 @@ RSpec.describe DeclareSchema::Model::HabtmModelShim do
30
29
  let(:reflection) { double("reflection", join_table: join_table,
31
30
  foreign_key: foreign_keys.first,
32
31
  association_foreign_key: foreign_keys.last,
33
- active_record: User,
34
- class_name: 'Customer',
35
- klass: Customer) }
32
+ active_record: foreign_key_classes.first,
33
+ class_name: 'Parent1') }
36
34
  it 'returns a new object' do
37
35
  result = described_class.from_reflection(reflection)
38
36
 
39
37
  expect(result).to be_a(described_class)
40
- expect(result.foreign_keys).to eq(foreign_keys.reverse)
41
- expect(result.parent_table_names).to eq(parent_table_names.reverse)
42
38
  end
43
39
  end
44
40
  end
45
41
 
46
42
  describe 'instance methods' do
47
- subject { described_class.new(join_table, foreign_keys, parent_table_names, connection: connection) }
43
+ let(:connection) { instance_double(ActiveRecord::Base.connection.class, "connection") }
44
+
45
+ subject { described_class.new(join_table, foreign_keys, foreign_key_classes, connection) }
48
46
 
49
47
  describe '#initialize' do
50
48
  it 'stores initialization attributes' do
51
49
  expect(subject.join_table).to eq(join_table)
52
- expect(subject.foreign_keys).to eq(foreign_keys.reverse)
50
+ expect(subject.foreign_keys).to eq(foreign_keys)
51
+ expect(subject.foreign_key_classes).to be(foreign_key_classes)
52
+ expect(subject.connection).to be(connection)
53
53
  end
54
54
  end
55
55
 
@@ -67,52 +67,51 @@ RSpec.describe DeclareSchema::Model::HabtmModelShim do
67
67
 
68
68
  describe '#field_specs' do
69
69
  it 'returns 2 field specs' do
70
- field_specs = subject.field_specs
71
- expect(field_specs.size).to eq(2), field_specs.inspect
72
-
73
- expect(field_specs[foreign_keys.first]).to be_a(::DeclareSchema::Model::FieldSpec)
74
- expect(field_specs[foreign_keys.first].model).to eq(subject)
75
- expect(field_specs[foreign_keys.first].name.to_s).to eq(foreign_keys.first)
76
- expect(field_specs[foreign_keys.first].type).to eq(:integer)
77
- expect(field_specs[foreign_keys.first].position).to eq(1)
78
-
79
- expect(field_specs[foreign_keys.last]).to be_a(::DeclareSchema::Model::FieldSpec)
80
- expect(field_specs[foreign_keys.last].model).to eq(subject)
81
- expect(field_specs[foreign_keys.last].name.to_s).to eq(foreign_keys.last)
82
- expect(field_specs[foreign_keys.last].type).to eq(:integer)
83
- expect(field_specs[foreign_keys.last].position).to eq(0)
70
+ result = subject.field_specs
71
+ expect(result.size).to eq(2), result.inspect
72
+
73
+ expect(result[foreign_keys.first]).to be_a(::DeclareSchema::Model::FieldSpec)
74
+ expect(result[foreign_keys.first].model).to eq(subject)
75
+ expect(result[foreign_keys.first].name.to_s).to eq(foreign_keys.first)
76
+ expect(result[foreign_keys.first].type).to eq(:integer)
77
+ expect(result[foreign_keys.first].position).to eq(0)
78
+
79
+ expect(result[foreign_keys.last]).to be_a(::DeclareSchema::Model::FieldSpec)
80
+ expect(result[foreign_keys.last].model).to eq(subject)
81
+ expect(result[foreign_keys.last].name.to_s).to eq(foreign_keys.last)
82
+ expect(result[foreign_keys.last].type).to eq(:integer)
83
+ expect(result[foreign_keys.last].position).to eq(1)
84
84
  end
85
85
  end
86
86
 
87
87
  describe '#primary_key' do
88
- it 'returns false because there is no single-column PK for ActiveRecord to use' do
89
- expect(subject.primary_key).to eq(false)
88
+ it 'returns false' do
89
+ expect(subject._declared_primary_key).to eq(false)
90
90
  end
91
91
  end
92
92
 
93
93
  describe '#_declared_primary_key' do
94
- it 'returns the foreign key pair that are used as the primary key in the database' do
95
- expect(subject._declared_primary_key).to eq(["customer_id", "user_id"])
94
+ it 'returns false' do
95
+ expect(subject._declared_primary_key).to eq(false)
96
96
  end
97
97
  end
98
98
 
99
99
  describe '#index_definitions_with_primary_key' do
100
100
  it 'returns 2 index definitions' do
101
- index_definitions = subject.index_definitions_with_primary_key
102
- expect(index_definitions.size).to eq(2), index_definitions.inspect
101
+ result = subject.index_definitions_with_primary_key
102
+ expect(result.size).to eq(2), result.inspect
103
103
 
104
- expect(index_definitions.last).to be_a(::DeclareSchema::Model::IndexDefinition)
105
- expect(index_definitions.last.name).to eq('PRIMARY')
106
- expect(index_definitions.last.fields).to eq(foreign_keys.reverse)
107
- expect(index_definitions.last.unique).to be_truthy
104
+ expect(result.first).to be_a(::DeclareSchema::Model::IndexDefinition)
105
+ expect(result.first.name).to eq('PRIMARY')
106
+ expect(result.first.fields).to eq(['parent_1_id', 'parent_2_id'])
107
+ expect(result.first.unique).to be_truthy
108
108
  end
109
109
  end
110
110
 
111
111
  context 'when table and foreign key names are long' do
112
112
  let(:join_table) { "advertiser_campaigns_tracking_pixels" }
113
- let(:foreign_keys_and_table_names) { [["advertiser_id", "advertisers"], ["campaign_id", "campaigns"]] }
114
- let(:foreign_keys) { foreign_keys_and_table_names.map(&:first) }
115
- let(:parent_table_names) { foreign_keys_and_table_names.map(&:last) }
113
+ let(:foreign_keys) { ['advertiser_campaign', 'tracking_pixel'] }
114
+ let(:foreign_key_classes) { [Table1, Table2] }
116
115
 
117
116
  before do
118
117
  class Table1 < ActiveRecord::Base
@@ -125,40 +124,19 @@ RSpec.describe DeclareSchema::Model::HabtmModelShim do
125
124
  end
126
125
 
127
126
  it 'returns two index definitions and does not raise a IndexNameTooLongError' do
128
- indexes = subject.index_definitions_with_primary_key
129
- expect(indexes.size).to eq(2), indexes.inspect
130
- expect(indexes.last).to be_a(::DeclareSchema::Model::IndexDefinition)
131
- expect(indexes.last.name).to eq('PRIMARY')
132
- expect(indexes.last.fields).to eq(foreign_keys)
133
- expect(indexes.last.unique).to be_truthy
134
- expect(indexes.first).to be_a(::DeclareSchema::Model::IndexDefinition)
135
- expect(indexes.first.name).to eq('index_advertiser_campaigns_tracking_pixels_on_campaign_id')
136
- expect(indexes.first.fields).to eq([foreign_keys.last])
137
- expect(indexes.first.unique).to be_falsey
127
+ result = subject.index_definitions_with_primary_key
128
+ expect(result.size).to eq(2), result.inspect
129
+ expect(result.first).to be_a(::DeclareSchema::Model::IndexDefinition)
130
+ expect(result.first.name).to eq('PRIMARY')
131
+ expect(result.first.fields).to eq(['advertiser_campaign', 'tracking_pixel'])
132
+ expect(result.first.unique).to be_truthy
138
133
  end
139
134
  end
140
135
 
141
136
  describe '#index_definitions' do
142
- it 'returns index_definitions' do
143
- indexes = subject.index_definitions
144
- expect(indexes.size).to eq(1), indexes.inspect
145
- expect(indexes.first.columns).to eq(["user_id"])
146
- options = [:name, :unique, :where].map { |k| [k, indexes.first.send(k)] }.to_h
147
- expect(options).to eq(name: "index_customers_users_on_user_id",
148
- unique: false,
149
- where: nil)
150
- end
151
- end
152
-
153
- describe '#index_definitions_with_primary_key' do
154
137
  it 'returns index_definitions_with_primary_key' do
155
- indexes = subject.index_definitions_with_primary_key
156
- expect(indexes.size).to eq(2), indexes.inspect
157
- expect(indexes.last.columns).to eq(["customer_id", "user_id"])
158
- options = [:name, :unique, :where].map { |k| [k, indexes.last.send(k)] }.to_h
159
- expect(options).to eq(name: "PRIMARY",
160
- unique: true,
161
- where: nil)
138
+ result = subject.index_definitions
139
+ expect(result.size).to eq(2), result.inspect
162
140
  end
163
141
  end
164
142
 
@@ -170,11 +148,18 @@ RSpec.describe DeclareSchema::Model::HabtmModelShim do
170
148
 
171
149
  describe '#constraint_specs' do
172
150
  it 'returns 2 foreign keys' do
173
- constraints = subject.constraint_specs
174
- expect(constraints.map(&:key)).to eq([
175
- ["customers", "customer_id", :delete],
176
- ["users", "user_id", :delete]
177
- ])
151
+ result = subject.constraint_specs
152
+ expect(result.size).to eq(2), result.inspect
153
+
154
+ expect(result.first).to be_a(::DeclareSchema::Model::ForeignKeyDefinition)
155
+ expect(result.first.foreign_key).to eq(foreign_keys.first)
156
+ expect(result.first.parent_table_name).to be(Parent1.table_name)
157
+ expect(result.first.on_delete_cascade).to be_truthy
158
+
159
+ expect(result.last).to be_a(::DeclareSchema::Model::ForeignKeyDefinition)
160
+ expect(result.last.foreign_key).to eq(foreign_keys.last)
161
+ expect(result.last.parent_table_name).to be(Parent2.table_name)
162
+ expect(result.last.on_delete_cascade).to be_truthy
178
163
  end
179
164
  end
180
165
  end