declare_schema 1.3.6 → 1.4.0.colin.1

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.
@@ -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