declare_schema 0.6.3 → 0.6.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a2f9216c43a3ba2d669d966a4f645edb0faa78a6697cb2a008f017bab2d7534
4
- data.tar.gz: 3223fad1929f4d75c41e12d8cabd20b6a95775308edf4e4e078b8dcd34ec54cc
3
+ metadata.gz: 523660550181d173c4ff4d6dc181b6d790419a3fdfb1e956076eed2d4c9f7f3b
4
+ data.tar.gz: '0380d2f800fd64c770c87631090ee792875034211b6ba9d18f5acc34e5ba9f0b'
5
5
  SHA512:
6
- metadata.gz: 45318951ec1e963d3eea783def6ee7d9828cdf1826e14ae5977c48cd7f1599bb04712ef95899750ed40a21cccfdd0789b24c993e080d898a10e689c7a9618072
7
- data.tar.gz: eb1cf73bb3628ea498785b74b4d78029cd2858de1286657ca3f625181100c9daddfd1cb21c7c079f1518ee388e7112e30923ead79dd6e4d6333ee562f2daa2e2
6
+ metadata.gz: 824d98b6bb3b30d0eebf594db7cead5e954fed227eefdb8f627811da3a7f8c9bc76f62552c3c3a87b0ff3adf51a95a1e666e903d6993430aaa3521607b6ee260
7
+ data.tar.gz: e8b45fb7dd6df1b314b3ada7e3da6223c631911ce88233165dff486ddb0bfc4a09e42255c018e7d00a456f95d0c1a8af010fe5531f6c2d64516cf3a09f51eb19
data/CHANGELOG.md CHANGED
@@ -4,7 +4,11 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
5
  Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [0.6.3] - UNRELEASED
7
+ ## [0.6.4] - 2020-02-08
8
+ - Fixed a bug where the generated call to add_foreign_key() was not setting `column:`,
9
+ so it only worked in cases where Rails could infer the foreign key by convention.
10
+
11
+ ## [0.6.3] - 2020-01-21
8
12
  ### Added
9
13
  - Added `add_foreign_key` native rails call in `DeclareSchema::Model::ForeignKeyDefinition#to_add_statement`.
10
14
 
@@ -12,7 +16,7 @@ Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0
12
16
  - Fixed a bug in migration generation caused by `DeclareSchema::Migration#create_constraints`
13
17
  calling `DeclareSchema::Model::ForeignKeyDefinition#to_add_statement` with unused parameters.
14
18
 
15
- - Fixed a bug in `DeclareSchema::Migration#remove_foreign_key` where special characters would not be quoted properly.
19
+ - Fixed a bug in `DeclareSchema::Migration#remove_foreign_key` where special characters would not be quoted properly.
16
20
 
17
21
  ## [0.6.2] - 2021-01-06
18
22
  ### Added
@@ -110,6 +114,7 @@ using the appropriate Rails configuration attributes.
110
114
  ### Added
111
115
  - Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
112
116
 
117
+ [0.6.4]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.6.4
113
118
  [0.6.3]: https://github.com/Invoca/declare_schema/compare/v0.6.2...v0.6.3
114
119
  [0.6.2]: https://github.com/Invoca/declare_schema/compare/v0.6.1...v0.6.2
115
120
  [0.6.1]: https://github.com/Invoca/declare_schema/compare/v0.6.0...v0.6.1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- declare_schema (0.6.3)
4
+ declare_schema (0.6.4)
5
5
  rails (>= 4.2)
6
6
 
7
7
  GEM
@@ -5,21 +5,21 @@ module DeclareSchema
5
5
  class ForeignKeyDefinition
6
6
  include Comparable
7
7
 
8
- attr_reader :constraint_name, :model, :foreign_key, :options, :on_delete_cascade
8
+ attr_reader :constraint_name, :model, :foreign_key, :foreign_key_name, :options, :on_delete_cascade
9
9
 
10
10
  def initialize(model, foreign_key, options = {})
11
11
  @model = model
12
- @foreign_key = foreign_key.presence
12
+ @foreign_key = foreign_key.to_s.presence
13
13
  @options = options
14
14
 
15
15
  @child_table = model.table_name # unless a table rename, which would happen when a class is renamed??
16
- @parent_table_name = options[:parent_table]
17
- @foreign_key_name = options[:foreign_key] || self.foreign_key
18
- @index_name = options[:index_name] || model.connection.index_name(model.table_name, column: foreign_key)
19
- @constraint_name = options[:constraint_name] || @index_name || ''
20
- @on_delete_cascade = options[:dependent] == :delete
16
+ @parent_table_name = options[:parent_table]&.to_s
17
+ @foreign_key_name = options[:foreign_key]&.to_s || @foreign_key
18
+ @index_name = options[:index_name]&.to_s || model.connection.index_name(model.table_name, column: @foreign_key_name)
21
19
 
22
20
  # Empty constraint lets mysql generate the name
21
+ @constraint_name = options[:constraint_name]&.to_s || @index_name&.to_s || ''
22
+ @on_delete_cascade = options[:dependent] == :delete
23
23
  end
24
24
 
25
25
  class << self
@@ -28,11 +28,12 @@ module DeclareSchema
28
28
  constraints = show_create_table.split("\n").map { |line| line.strip if line['CONSTRAINT'] }.compact
29
29
 
30
30
  constraints.map do |fkc|
31
- options = {}
32
31
  name, foreign_key, parent_table = fkc.match(/CONSTRAINT `([^`]*)` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)`/).captures
33
- options[:constraint_name] = name
34
- options[:parent_table] = parent_table
35
- options[:foreign_key] = foreign_key
32
+ options = {
33
+ constraint_name: name,
34
+ parent_table: parent_table,
35
+ foreign_key: foreign_key
36
+ }
36
37
  options[:dependent] = :delete if fkc['ON DELETE CASCADE']
37
38
 
38
39
  new(model, foreign_key, options)
@@ -40,20 +41,37 @@ module DeclareSchema
40
41
  end
41
42
  end
42
43
 
44
+ # returns the parent class as a Class object
45
+ # or nil if no :class_name option given
46
+ def parent_class
47
+ if (class_name = options[:class_name])
48
+ if class_name.is_a?(Class)
49
+ class_name
50
+ else
51
+ class_name.to_s.constantize
52
+ end
53
+ end
54
+ end
55
+
43
56
  def parent_table_name
44
57
  @parent_table_name ||=
45
- if (klass = options[:class_name])
46
- klass = klass.to_s.constantize unless klass.is_a?(Class)
47
- klass.try(:table_name)
48
- end || foreign_key.sub(/_id\z/, '').camelize.constantize.table_name
58
+ parent_class&.try(:table_name) ||
59
+ foreign_key.sub(/_id\z/, '').camelize.constantize.table_name
49
60
  end
50
61
 
51
- attr_writer :parent_table_name
52
-
53
62
  def to_add_statement
54
- "add_foreign_key(#{@child_table.inspect}, #{parent_table_name.inspect}, name: #{@constraint_name.inspect})"
63
+ "add_foreign_key(#{@child_table.inspect}, #{parent_table_name.inspect}, " +
64
+ "column: #{@foreign_key_name.inspect}, name: #{@constraint_name.inspect})"
65
+ end
66
+
67
+ def <=>(rhs)
68
+ key <=> rhs.send(:key)
55
69
  end
56
70
 
71
+ alias eql? ==
72
+
73
+ private
74
+
57
75
  def key
58
76
  @key ||= [@child_table, parent_table_name, @foreign_key_name, @on_delete_cascade].map(&:to_s)
59
77
  end
@@ -61,12 +79,6 @@ module DeclareSchema
61
79
  def hash
62
80
  key.hash
63
81
  end
64
-
65
- def <=>(rhs)
66
- key <=> rhs.key
67
- end
68
-
69
- alias eql? ==
70
82
  end
71
83
  end
72
84
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeclareSchema
4
- VERSION = "0.6.3"
4
+ VERSION = "0.6.4"
5
5
  end
@@ -369,7 +369,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
369
369
 
370
370
  add_index :adverts, [:category_id], name: 'on_category_id'
371
371
 
372
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" if defined?(Mysql2)}
372
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" if defined?(Mysql2)}
373
373
  EOS
374
374
  .and migrate_down(<<~EOS.strip)
375
375
  remove_column :adverts, :category_id
@@ -397,8 +397,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
397
397
 
398
398
  add_index :adverts, [:c_id], name: 'on_c_id'
399
399
 
400
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
401
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
400
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
401
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
402
402
  EOS
403
403
  )
404
404
 
@@ -417,8 +417,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
417
417
  migrate_up(<<~EOS.strip)
418
418
  add_column :adverts, :category_id, :integer, limit: 8, null: false
419
419
 
420
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
421
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
420
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
421
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
422
422
  EOS
423
423
  )
424
424
 
@@ -439,8 +439,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
439
439
 
440
440
  add_index :adverts, [:category_id], name: 'my_index'
441
441
 
442
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
443
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
442
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
443
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
444
444
  EOS
445
445
  )
446
446
 
@@ -465,8 +465,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
465
465
  add_column :adverts, :updated_at, :datetime
466
466
  add_column :adverts, :lock_version, :integer, null: false, default: 1
467
467
 
468
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
469
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
468
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
469
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
470
470
  EOS
471
471
  .and migrate_down(<<~EOS.strip)
472
472
  remove_column :adverts, :created_at
@@ -498,8 +498,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
498
498
 
499
499
  add_index :adverts, [:title], name: 'on_title'
500
500
 
501
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
502
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
501
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
502
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
503
503
  EOS
504
504
  )
505
505
 
@@ -519,8 +519,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
519
519
 
520
520
  add_index :adverts, [:title], unique: true, name: 'on_title'
521
521
 
522
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
523
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
522
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
523
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
524
524
  EOS
525
525
  )
526
526
 
@@ -540,8 +540,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
540
540
 
541
541
  add_index :adverts, [:title], name: 'my_index'
542
542
 
543
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
544
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
543
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
544
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
545
545
  EOS
546
546
  )
547
547
 
@@ -559,8 +559,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
559
559
 
560
560
  add_index :adverts, [:title], name: 'on_title'
561
561
 
562
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
563
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
562
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
563
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
564
564
  EOS
565
565
  )
566
566
 
@@ -578,8 +578,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
578
578
 
579
579
  add_index :adverts, [:title], unique: true, name: 'my_index'
580
580
 
581
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
582
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
581
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
582
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
583
583
  EOS
584
584
  )
585
585
 
@@ -597,8 +597,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
597
597
 
598
598
  add_index :adverts, [:title, :category_id], name: 'on_title_and_category_id'
599
599
 
600
- #{"add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
601
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
600
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
601
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
602
602
  EOS
603
603
  )
604
604
 
@@ -634,8 +634,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
634
634
  "add_index :ads, [:id], unique: true, name: 'PRIMARY'\n"
635
635
  elsif defined?(Mysql2)
636
636
  "execute \"ALTER TABLE ads DROP PRIMARY KEY, ADD PRIMARY KEY (id)\"\n\n" +
637
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_category_id\")\n" +
638
- "add_foreign_key(\"adverts\", \"categories\", name: \"index_adverts_on_c_id\")"
637
+ "add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
638
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")"
639
639
  end}
640
640
  EOS
641
641
  .and migrate_down(<<~EOS.strip)
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/model/foreign_key_definition'
4
+
5
+ RSpec.describe DeclareSchema::Model::ForeignKeyDefinition do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+
9
+ class Network < ActiveRecord::Base
10
+ fields do
11
+ name :string, limit: 127, index: true
12
+
13
+ timestamps
14
+ end
15
+ end
16
+ end
17
+
18
+ let(:model_class) { Network }
19
+
20
+ describe 'instance methods' do
21
+ let(:connection) { instance_double(ActiveRecord::Base.connection.class) }
22
+ let(:model) { instance_double('Model', table_name: 'models', connection: connection) }
23
+ let(:foreign_key) { :network_id }
24
+ let(:options) { {} }
25
+ subject { described_class.new(model, foreign_key, options)}
26
+
27
+ before do
28
+ allow(connection).to receive(:index_name).with('models', column: 'network_id') { 'on_network_id' }
29
+ end
30
+
31
+ describe '#initialize' do
32
+ it 'normalizes symbols to strings' do
33
+ expect(subject.foreign_key).to eq('network_id')
34
+ expect(subject.parent_table_name).to eq('networks')
35
+ end
36
+
37
+ context 'when most options passed' do
38
+ let(:options) { { parent_table: :networks, foreign_key: :the_network_id, index_name: :index_on_network_id } }
39
+
40
+ it 'normalizes symbols to strings' do
41
+ expect(subject.foreign_key).to eq('network_id')
42
+ expect(subject.foreign_key_name).to eq('the_network_id')
43
+ expect(subject.parent_table_name).to eq('networks')
44
+ expect(subject.foreign_key).to eq('network_id')
45
+ expect(subject.constraint_name).to eq('index_on_network_id')
46
+ expect(subject.on_delete_cascade).to be_falsey
47
+ end
48
+ end
49
+
50
+ context 'when all options passed' do
51
+ let(:foreign_key) { nil }
52
+ let(:options) { { parent_table: :networks, foreign_key: :the_network_id, index_name: :index_on_network_id,
53
+ constraint_name: :constraint_1, dependent: :delete } }
54
+
55
+ it 'normalizes symbols to strings' do
56
+ expect(subject.foreign_key).to be_nil
57
+ expect(subject.foreign_key_name).to eq('the_network_id')
58
+ expect(subject.parent_table_name).to eq('networks')
59
+ expect(subject.constraint_name).to eq('constraint_1')
60
+ expect(subject.on_delete_cascade).to be_truthy
61
+ end
62
+ end
63
+ end
64
+
65
+ describe '#to_add_statement' do
66
+ it 'returns add_foreign_key command' do
67
+ expect(subject.to_add_statement).to eq('add_foreign_key("models", "networks", column: "network_id", name: "on_network_id")')
68
+ end
69
+ end
70
+ end
71
+
72
+ describe 'class << self' do
73
+ let(:connection) { instance_double(ActiveRecord::Base.connection.class) }
74
+ let(:model) { instance_double('Model', table_name: 'models', connection: connection) }
75
+ let(:old_table_name) { 'networks' }
76
+ before do
77
+ allow(connection).to receive(:quote_table_name).with('networks') { 'networks' }
78
+ allow(connection).to receive(:select_rows) { [['CONSTRAINT `constraint` FOREIGN KEY (`network_id`) REFERENCES `networks` (`id`)']] }
79
+ allow(connection).to receive(:index_name).with('models', column: 'network_id') { }
80
+ end
81
+
82
+ describe '.for_model' do
83
+ subject { described_class.for_model(model, old_table_name) }
84
+
85
+ it 'returns new object' do
86
+ expect(subject.size).to eq(1), subject.inspect
87
+ expect(subject.first).to be_kind_of(described_class)
88
+ expect(subject.first.foreign_key).to eq('network_id')
89
+ end
90
+ end
91
+ end
92
+ # TODO: fill out remaining tests
93
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: declare_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca Development adapted from hobo_fields by Tom Locke
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-19 00:00:00.000000000 Z
11
+ date: 2021-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -82,6 +82,7 @@ files:
82
82
  - spec/lib/declare_schema/generator_spec.rb
83
83
  - spec/lib/declare_schema/interactive_primary_key_spec.rb
84
84
  - spec/lib/declare_schema/migration_generator_spec.rb
85
+ - spec/lib/declare_schema/model/foreign_key_definition_spec.rb
85
86
  - spec/lib/declare_schema/model/index_definition_spec.rb
86
87
  - spec/lib/declare_schema/model/table_options_definition_spec.rb
87
88
  - spec/lib/declare_schema/prepare_testapp.rb
@@ -93,7 +94,7 @@ homepage: https://github.com/Invoca/declare_schema
93
94
  licenses: []
94
95
  metadata:
95
96
  allowed_push_host: https://rubygems.org
96
- post_install_message:
97
+ post_install_message:
97
98
  rdoc_options: []
98
99
  require_paths:
99
100
  - lib
@@ -109,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
110
  version: 1.3.6
110
111
  requirements: []
111
112
  rubygems_version: 3.0.3
112
- signing_key:
113
+ signing_key:
113
114
  specification_version: 4
114
115
  summary: Database schema declaration and migration generator for Rails
115
116
  test_files: []