declare_schema 0.3.0.pre.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3364c39b6579bb69804417a10b5b287208e6fdfe5a23bf57b6b3f928f69fe539
4
- data.tar.gz: 2fbc6abab32d750ef1af34d6888b5954ee27da2563acd8595728d3d23d184244
3
+ metadata.gz: f3ae0814480b116b32a822887c83612b33458cc910384ae0c2122e547757f141
4
+ data.tar.gz: 133b7bd6d7d91dae9320a4e8002a8591e43ebb97f57013cbe266cef40a169088
5
5
  SHA512:
6
- metadata.gz: 7e884c085c0d72f1146d7b7f52abbf1f44b19389e2f96e2858b855b11041c94406b0be159a300366d0abeec2f36cf9056d3eddd61352600c780a992ca3971817
7
- data.tar.gz: 1d45f652bd8d0de74b71fec913c4005be8f3212de7fa7942ad587d67059f67115ce8d797be9d71121e792ab66aee84c2adaaa013766b6d96cb21eda1d35522b4
6
+ metadata.gz: 77b840eb5feb07d38c4fd96f4212d4c81f19c61a2aa2b4bbffb4f4f11594ba55c30e65ca4b77a68e7b29448f7762dba52782f1845307c5bbc02f7603f080c2e8
7
+ data.tar.gz: 2f85affbd44a6973595883afa01766ede6c950a70c4e783f3064e5c2a59ec5c71a3731d7d484bab133c18c698584077e2c14a8b98c81ce024e2e55bae59dabba
@@ -4,10 +4,19 @@ 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.3.0] - Unreleased
7
+ ## [0.3.0] - 2020-11-02
8
8
  ### Added
9
+ - Added support for `belongs_to optional:`.
10
+ If given, it is passed through to `ActiveRecord`'s `belong_to`.
11
+ If not given in Rails 5+, the `optional:` value is set equal to the `null:` value (default: `false`) and that
12
+ is passed to `ActiveRecord`'s `belong_to`.
13
+ Similarly, if `null:` is not given, it is inferred from `optional:`.
14
+ If both are given, their values are respected, even if contradictory;
15
+ this is a legitimate case when migrating to/from an optional association.
9
16
  - Added a new callback `before_generating_migration` to the `Migrator` that can be
10
17
  defined in order to custom load more models that might be missed by `eager_load!`
18
+ ### Fixed
19
+ - Migrations are now generated where the `[4.2]` is only applied after `ActiveRecord::Migration` in Rails 5+ (since Rails 4 didn't know about that notation).
11
20
 
12
21
  ## [0.2.0] - 2020-10-26
13
22
  ### Added
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- declare_schema (0.3.0.pre.2)
4
+ declare_schema (0.3.0)
5
5
  rails (>= 4.2)
6
6
 
7
7
  GEM
@@ -106,17 +106,14 @@ module DeclareSchema
106
106
  end
107
107
 
108
108
  # Extend belongs_to so that it creates a FieldSpec for the foreign key
109
- def belongs_to(name, *args, &block)
110
- if args.size == 0 || (args.size == 1 && args[0].is_a?(Proc))
111
- options = {}
112
- args.push(options)
113
- elsif args.size == 1
114
- options = args[0]
115
- else
116
- options = args[1]
117
- end
109
+ def belongs_to(name, scope = nil, **options, &block)
118
110
  column_options = {}
119
- column_options[:null] = options.delete(:null) || false
111
+
112
+ column_options[:null] = if options.has_key?(:null)
113
+ options.delete(:null)
114
+ elsif options.has_key?(:optional)
115
+ options[:optional] # infer :null from :optional
116
+ end || false
120
117
  column_options[:default] = options.delete(:default) if options.has_key?(:default)
121
118
  column_options[:limit] = options.delete(:limit) if options.has_key?(:limit)
122
119
 
@@ -129,20 +126,27 @@ module DeclareSchema
129
126
  fk_options[:constraint_name] = options.delete(:constraint) if options.has_key?(:constraint)
130
127
  fk_options[:index_name] = index_options[:name]
131
128
 
129
+ fk = options[:foreign_key]&.to_s || "#{name}_id"
130
+
131
+ if !options.has_key?(:optional) && Rails::VERSION::MAJOR >= 5
132
+ options[:optional] = column_options[:null] # infer :optional from :null
133
+ end
134
+
132
135
  fk_options[:dependent] = options.delete(:far_end_dependent) if options.has_key?(:far_end_dependent)
133
- super(name, *args, &block).tap do |_bt|
134
- refl = reflections[name.to_s] or raise "Couldn't find reflection #{name} in #{reflections.keys}"
135
- fkey = refl.foreign_key
136
- declare_field(fkey.to_sym, :integer, column_options)
137
- if refl.options[:polymorphic]
138
- foreign_type = options[:foreign_type] || "#{name}_type"
139
- declare_polymorphic_type_field(foreign_type, column_options)
140
- index([foreign_type, fkey], index_options) if index_options[:name] != false
141
- else
142
- index(fkey, index_options) if index_options[:name] != false
143
- options[:constraint_name] = options
144
- constraint(fkey, fk_options) if fk_options[:constraint_name] != false
145
- end
136
+
137
+ super(name, scope, options)
138
+
139
+ refl = reflections[name.to_s] or raise "Couldn't find reflection #{name} in #{reflections.keys}"
140
+ fkey = refl.foreign_key or raise "Couldn't find foreign_key for #{name} in #{refl.inspect}"
141
+ declare_field(fkey.to_sym, :integer, column_options)
142
+ if refl.options[:polymorphic]
143
+ foreign_type = options[:foreign_type] || "#{name}_type"
144
+ declare_polymorphic_type_field(foreign_type, column_options)
145
+ index([foreign_type, fkey], index_options) if index_options[:name] != false
146
+ else
147
+ index(fkey, index_options) if index_options[:name] != false
148
+ options[:constraint_name] = options
149
+ constraint(fkey, fk_options) if fk_options[:constraint_name] != false
146
150
  end
147
151
  end
148
152
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeclareSchema
4
- VERSION = "0.3.0.pre.2"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -1,4 +1,4 @@
1
- class <%= @migration_class_name %> < ActiveRecord::Migration<%= ('[4.2]' if Rails::VERSION::MAJOR >= 5) %>
1
+ class <%= @migration_class_name %> < (Rails::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)
2
2
  def self.up
3
3
  <%= @up %>
4
4
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rails'
4
+
3
5
  RSpec.describe 'DeclareSchema Migration Generator' do
4
6
  before do
5
7
  load File.expand_path('prepare_testapp.rb', __dir__)
@@ -53,7 +55,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
53
55
 
54
56
  add_index :adverts, [:id], unique: true, name: 'PRIMARY_KEY'
55
57
  EOS
56
- # TODO: ^ add_index should not be there?
58
+ # TODO: ^ TECH-4975 add_index should not be there
57
59
 
58
60
  expect(down).to eq(<<~EOS.strip)
59
61
  remove_column :adverts, :body
@@ -129,7 +131,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
129
131
  end
130
132
  end
131
133
 
132
- up, down = Generators::DeclareSchema::Migration::Migrator.run
134
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
133
135
  expect(up).to eq("add_column :adverts, :price, :integer, limit: 2")
134
136
 
135
137
  # Now run the migration, then change the limit:
@@ -154,7 +156,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
154
156
  end
155
157
  end
156
158
 
157
- up, down = Generators::DeclareSchema::Migration::Migrator.run
159
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
158
160
  expect(up).to eq("add_column :adverts, :price, :decimal")
159
161
 
160
162
  # Limits are generally not needed for `text` fields, because by default, `text` fields will use the maximum size
@@ -170,7 +172,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
170
172
  end
171
173
  end
172
174
 
173
- up, down = Generators::DeclareSchema::Migration::Migrator.run
175
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
174
176
  expect(up).to eq(<<~EOS.strip)
175
177
  add_column :adverts, :price, :decimal
176
178
  add_column :adverts, :notes, :text, null: false
@@ -194,7 +196,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
194
196
  end
195
197
  end
196
198
 
197
- up, down = Generators::DeclareSchema::Migration::Migrator.run
199
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
198
200
  expect(up).to eq(<<~EOS.strip)
199
201
  add_column :adverts, :notes, :text, null: false, limit: 4294967295
200
202
  add_column :adverts, :description, :text, null: false, limit: 255
@@ -266,7 +268,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
266
268
  end
267
269
  end
268
270
 
269
- up, down = Generators::DeclareSchema::Migration::Migrator.run
271
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
270
272
  ActiveRecord::Migration.class_eval up
271
273
  Advert.connection.schema_cache.clear!
272
274
  Advert.reset_column_information
@@ -278,6 +280,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
278
280
 
279
281
  class Category < ActiveRecord::Base; end
280
282
  class Advert < ActiveRecord::Base
283
+ fields do
284
+ name :string, limit: 255, null: true
285
+ end
281
286
  belongs_to :category
282
287
  end
283
288
 
@@ -298,9 +303,10 @@ RSpec.describe 'DeclareSchema Migration Generator' do
298
303
 
299
304
  class Category < ActiveRecord::Base; end
300
305
  class Advert < ActiveRecord::Base
306
+ fields { }
301
307
  belongs_to :category, foreign_key: "c_id", class_name: 'Category'
302
308
  end
303
- up, down = Generators::DeclareSchema::Migration::Migrator.run
309
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
304
310
  expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
305
311
  add_column :adverts, :c_id, :integer, limit: 8, null: false
306
312
  add_index :adverts, [:c_id], name: 'on_c_id'
@@ -313,9 +319,10 @@ RSpec.describe 'DeclareSchema Migration Generator' do
313
319
 
314
320
  class Category < ActiveRecord::Base; end
315
321
  class Advert < ActiveRecord::Base
322
+ fields { }
316
323
  belongs_to :category, index: false
317
324
  end
318
- up, down = Generators::DeclareSchema::Migration::Migrator.run
325
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
319
326
  expect(up.gsub(/\n+/, "\n")).to eq("add_column :adverts, :category_id, :integer, limit: 8, null: false")
320
327
 
321
328
  Advert.field_specs.delete(:category_id)
@@ -325,9 +332,10 @@ RSpec.describe 'DeclareSchema Migration Generator' do
325
332
 
326
333
  class Category < ActiveRecord::Base; end
327
334
  class Advert < ActiveRecord::Base
335
+ fields { }
328
336
  belongs_to :category, index: 'my_index'
329
337
  end
330
- up, down = Generators::DeclareSchema::Migration::Migrator.run
338
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
331
339
  expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
332
340
  add_column :adverts, :category_id, :integer, limit: 8, null: false
333
341
  add_index :adverts, [:category_id], name: 'my_index'
@@ -372,7 +380,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
372
380
  title :string, index: true, limit: 255, null: true
373
381
  end
374
382
  end
375
- up, down = Generators::DeclareSchema::Migration::Migrator.run
383
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
376
384
  expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
377
385
  add_column :adverts, :title, :string, limit: 255
378
386
  add_index :adverts, [:title], name: 'on_title'
@@ -387,7 +395,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
387
395
  title :string, index: true, unique: true, null: true, limit: 255
388
396
  end
389
397
  end
390
- up, down = Generators::DeclareSchema::Migration::Migrator.run
398
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
391
399
  expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
392
400
  add_column :adverts, :title, :string, limit: 255
393
401
  add_index :adverts, [:title], unique: true, name: 'on_title'
@@ -402,20 +410,20 @@ RSpec.describe 'DeclareSchema Migration Generator' do
402
410
  title :string, index: 'my_index', limit: 255, null: true
403
411
  end
404
412
  end
405
- up, down = Generators::DeclareSchema::Migration::Migrator.run
413
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
406
414
  expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
407
415
  add_column :adverts, :title, :string, limit: 255
408
416
  add_index :adverts, [:title], name: 'my_index'
409
417
  EOS
410
418
 
411
- Advert.index_specs.delete_if {|spec| spec.fields==["title"]}
419
+ Advert.index_specs.delete_if { |spec| spec.fields==["title"] }
412
420
 
413
421
  # You can ask for an index outside of the fields block
414
422
 
415
423
  class Advert < ActiveRecord::Base
416
424
  index :title
417
425
  end
418
- up, down = Generators::DeclareSchema::Migration::Migrator.run
426
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
419
427
  expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
420
428
  add_column :adverts, :title, :string, limit: 255
421
429
  add_index :adverts, [:title], name: 'on_title'
@@ -428,7 +436,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
428
436
  class Advert < ActiveRecord::Base
429
437
  index :title, unique: true, name: 'my_index'
430
438
  end
431
- up, down = Generators::DeclareSchema::Migration::Migrator.run
439
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
432
440
  expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
433
441
  add_column :adverts, :title, :string, limit: 255
434
442
  add_index :adverts, [:title], unique: true, name: 'my_index'
@@ -441,7 +449,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
441
449
  class Advert < ActiveRecord::Base
442
450
  index [:title, :category_id]
443
451
  end
444
- up, down = Generators::DeclareSchema::Migration::Migrator.run
452
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
445
453
  expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
446
454
  add_column :adverts, :title, :string, limit: 255
447
455
  add_index :adverts, [:title, :category_id], name: 'on_title_and_category_id'
@@ -544,7 +552,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
544
552
  title :string, default: "Untitled", limit: 255, null: true
545
553
  end
546
554
  end
547
- up, down = Generators::DeclareSchema::Migration::Migrator.run
555
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
548
556
  ActiveRecord::Migration.class_eval(up)
549
557
 
550
558
  class FancyAdvert < Advert
@@ -613,7 +621,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
613
621
  created_at :datetime
614
622
  end
615
623
  end
616
- up, down = Generators::DeclareSchema::Migration::Migrator.run(adverts: :ads)
624
+ up = Generators::DeclareSchema::Migration::Migrator.run(adverts: :ads).first
617
625
  expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
618
626
  rename_table :adverts, :ads
619
627
  add_column :ads, :created_at, :datetime, null: false
@@ -682,5 +690,106 @@ RSpec.describe 'DeclareSchema Migration Generator' do
682
690
  ActiveRecord::Migration.class_eval(up)
683
691
  expect(Ad.field_specs['company'].options[:validates].inspect).to eq("{:presence=>true, :uniqueness=>{:case_sensitive=>false}}")
684
692
  end
685
- end
686
693
 
694
+ if Rails::VERSION::MAJOR >= 5
695
+ describe 'belongs_to' do
696
+ before do
697
+ unless defined?(AdCategory)
698
+ class AdCategory < ActiveRecord::Base
699
+ fields { }
700
+ end
701
+ end
702
+
703
+ class Advert < ActiveRecord::Base
704
+ fields do
705
+ name :string, limit: 255, null: true
706
+ category_id :integer, limit: 8
707
+ nullable_category_id :integer, limit: 8, null: true
708
+ end
709
+ end
710
+ up = Generators::DeclareSchema::Migration::Migrator.run.first
711
+ ActiveRecord::Migration.class_eval(up)
712
+ end
713
+
714
+ it 'passes through optional: when given' do
715
+ class AdvertBelongsTo < ActiveRecord::Base
716
+ self.table_name = 'adverts'
717
+ fields { }
718
+ reset_column_information
719
+ belongs_to :ad_category, optional: true
720
+ end
721
+ expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional: true)
722
+ end
723
+
724
+ describe 'contradictory settings' do # contradictory settings are ok during migration
725
+ it 'passes through optional: true, null: false' do
726
+ class AdvertBelongsTo < ActiveRecord::Base
727
+ self.table_name = 'adverts'
728
+ fields { }
729
+ reset_column_information
730
+ belongs_to :ad_category, optional: true, null: false
731
+ end
732
+ expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional: true)
733
+ expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(false)
734
+ end
735
+
736
+ it 'passes through optional: false, null: true' do
737
+ class AdvertBelongsTo < ActiveRecord::Base
738
+ self.table_name = 'adverts'
739
+ fields { }
740
+ reset_column_information
741
+ belongs_to :ad_category, optional: false, null: true
742
+ end
743
+ expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional: false)
744
+ expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(true)
745
+ end
746
+ end
747
+
748
+ [false, true].each do |nullable|
749
+ context "nullable=#{nullable}" do
750
+ it 'infers optional: from null:' do
751
+ eval <<~EOS
752
+ class AdvertBelongsTo < ActiveRecord::Base
753
+ fields { }
754
+ belongs_to :ad_category, null: #{nullable}
755
+ end
756
+ EOS
757
+ expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional: nullable)
758
+ expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(nullable)
759
+ end
760
+
761
+ it 'infers null: from optional:' do
762
+ eval <<~EOS
763
+ class AdvertBelongsTo < ActiveRecord::Base
764
+ fields { }
765
+ belongs_to :ad_category, optional: #{nullable}
766
+ end
767
+ EOS
768
+ expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional: nullable)
769
+ expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(nullable)
770
+ end
771
+ end
772
+ end
773
+ end
774
+ end
775
+
776
+ describe 'migration base class' do
777
+ it 'adapts to Rails 4' do
778
+ class Advert < active_record_base_class.constantize
779
+ fields do
780
+ title :string, limit: 100
781
+ end
782
+ end
783
+
784
+ Rails::Generators.invoke('declare_schema:migration', %w[-n -m])
785
+
786
+ migrations = Dir.glob('db/migrate/*declare_schema_migration*.rb')
787
+ expect(migrations.size).to eq(1), migrations.inspect
788
+
789
+ migration_content = File.read(migrations.first)
790
+ first_line = migration_content.split("\n").first
791
+ base_class = first_line.split(' < ').last
792
+ expect(base_class).to eq("(Rails::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)")
793
+ end
794
+ end
795
+ end
@@ -18,6 +18,8 @@ require "#{TESTAPP_PATH}/config/environment"
18
18
  require 'rails/generators'
19
19
  Rails::Generators.configure!(Rails.application.config.generators)
20
20
 
21
+ ActiveRecord::Base.connection.schema_cache.clear!
22
+
21
23
  (ActiveRecord::Base.connection.tables - Generators::DeclareSchema::Migration::Migrator.always_ignore_tables).each do |table|
22
24
  ActiveRecord::Base.connection.execute("DROP TABLE #{ActiveRecord::Base.connection.quote_table_name(table)}")
23
25
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: declare_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0.pre.2
4
+ version: 0.3.0
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
11
  date: 2020-11-02 00:00:00.000000000 Z
@@ -84,7 +84,7 @@ homepage: https://github.com/Invoca/declare_schema
84
84
  licenses: []
85
85
  metadata:
86
86
  allowed_push_host: https://rubygems.org
87
- post_install_message:
87
+ post_install_message:
88
88
  rdoc_options: []
89
89
  require_paths:
90
90
  - lib
@@ -100,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
100
  version: 1.3.6
101
101
  requirements: []
102
102
  rubygems_version: 3.0.3
103
- signing_key:
103
+ signing_key:
104
104
  specification_version: 4
105
105
  summary: Database migration generator for Rails
106
106
  test_files: []