declare_schema 0.8.0.pre.2 → 0.8.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: 32f8ca5dee3bd43f6fc2250904ba539cdeee30f0bb10a6f5f69f5782c282a5a4
4
- data.tar.gz: 4326ccc969837a6e74979a4b1fe60dff834e32afea2406c417b4ac18d4cdc582
3
+ metadata.gz: ae6f3f47d3ad4fa0b1d2e30d8f34b7ac5825b690838492ac57846dcd53396e9a
4
+ data.tar.gz: 129d77729c08d2fb41e506571ead2a82dd76c0c1675c18556bc3811e0adf3362
5
5
  SHA512:
6
- metadata.gz: 9548f216b1992826bad36409a370678483743e10270cf35f56447e2873cb64bf48b3ad1c695585bbcc52c37d0327c0a340e0cf8f73ebf6fe09c4af739de0e2fe
7
- data.tar.gz: b7b9cad07de9fe0d54db96359c3f97a5c7150d12728dfe189dc66ab8574f6b19ff378826a09ef3ed233e439e6034b487e05b656537b147215e459a07621cc727
6
+ metadata.gz: 5b145fdd60646c467772034afa2a29e30d29a4d35445c7e769bab731c043cb38c8e0b365ac7f6dc416e93fafdc1edd6e77724085054a6a442934cc191e335fdf
7
+ data.tar.gz: 1356d29f00f1eb4a72b567c48c57c6683bcc56852dfb68a3252b521a74c6c0afcfdf5765d94a31d3322ee297465c3ca60ec611090cf3ad5dd935e2bc343285ed
data/CHANGELOG.md CHANGED
@@ -4,8 +4,9 @@ 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.8.0] - UNRELEASED
7
+ ## [0.8.0] - 2021-02-22
8
8
  ### Removed
9
+ - Removed assumption that primary key is named 'id'.
9
10
  - Removed `sql_type` that was confusing because it was actually the same as `type` (ex: :string) and not
10
11
  in fact the SQL type (ex: ``varchar(255)'`).
11
12
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- declare_schema (0.8.0.pre.2)
4
+ declare_schema (0.8.0)
5
5
  rails (>= 4.2)
6
6
 
7
7
  GEM
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rails'
4
+
3
5
  require 'declare_schema/extensions/module'
4
6
 
5
7
  module DeclareSchema
@@ -36,7 +38,7 @@ module DeclareSchema
36
38
 
37
39
  # eval avoids the ruby 1.9.2 "super from singleton method ..." error
38
40
 
39
- eval %(
41
+ eval <<~EOS
40
42
  def self.inherited(klass)
41
43
  unless klass.field_specs.has_key?(inheritance_column)
42
44
  fields do |f|
@@ -46,14 +48,14 @@ module DeclareSchema
46
48
  end
47
49
  super
48
50
  end
49
- )
51
+ EOS
50
52
  end
51
53
  end
52
54
  end
53
55
 
54
56
  module ClassMethods
55
57
  def index(fields, options = {})
56
- # don't double-index fields
58
+ # make index idempotent
57
59
  index_fields_s = Array.wrap(fields).map(&:to_s)
58
60
  unless index_definitions.any? { |index_spec| index_spec.fields == index_fields_s }
59
61
  index_definitions << ::DeclareSchema::Model::IndexDefinition.new(self, fields, options)
@@ -72,7 +74,7 @@ module DeclareSchema
72
74
  end
73
75
 
74
76
  # tell the migration generator to ignore the named index. Useful for existing indexes, or for indexes
75
- # that can't be automatically generated (for example: an prefix index in MySQL)
77
+ # that can't be automatically generated (for example: a prefix index in MySQL)
76
78
  def ignore_index(index_name)
77
79
  ignore_indexes << index_name.to_s
78
80
  end
@@ -83,10 +85,10 @@ module DeclareSchema
83
85
  # declarations.
84
86
  def declare_field(name, type, *args, **options)
85
87
  try(:field_added, name, type, args, options)
86
- add_serialize_for_field(name, type, options)
87
- add_formatting_for_field(name, type)
88
- add_validations_for_field(name, type, args, options)
89
- add_index_for_field(name, args, options)
88
+ _add_serialize_for_field(name, type, options)
89
+ _add_formatting_for_field(name, type)
90
+ _add_validations_for_field(name, type, args, options)
91
+ _add_index_for_field(name, args, options)
90
92
  field_specs[name] = ::DeclareSchema::Model::FieldSpec.new(self, name, type, position: field_specs.size, **options)
91
93
  attr_order << name unless attr_order.include?(name)
92
94
  end
@@ -95,20 +97,10 @@ module DeclareSchema
95
97
  if index_definitions.any?(&:primary_key?)
96
98
  index_definitions
97
99
  else
98
- index_definitions + [rails_default_primary_key]
100
+ index_definitions + [_rails_default_primary_key]
99
101
  end
100
102
  end
101
103
 
102
- def primary_key
103
- super || 'id'
104
- end
105
-
106
- private
107
-
108
- def rails_default_primary_key
109
- ::DeclareSchema::Model::IndexDefinition.new(self, [primary_key.to_sym], unique: true, name: DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME)
110
- end
111
-
112
104
  # Extend belongs_to so that it creates a FieldSpec for the foreign key
113
105
  def belongs_to(name, scope = nil, **options)
114
106
  column_options = {}
@@ -149,7 +141,7 @@ module DeclareSchema
149
141
  declare_field(fkey.to_sym, :integer, column_options)
150
142
  if refl.options[:polymorphic]
151
143
  foreign_type = options[:foreign_type] || "#{name}_type"
152
- declare_polymorphic_type_field(foreign_type, column_options)
144
+ _declare_polymorphic_type_field(foreign_type, column_options)
153
145
  index([foreign_type, fkey], index_options) if index_options[:name] != false
154
146
  else
155
147
  index(fkey, index_options) if index_options[:name] != false
@@ -157,26 +149,49 @@ module DeclareSchema
157
149
  end
158
150
  end
159
151
 
152
+ if ::Rails::VERSION::MAJOR < 5
153
+ def primary_key
154
+ super || 'id'
155
+ end
156
+ end
157
+
158
+ # returns the primary key (String) as declared with primary_key =
159
+ # unlike the `primary_key` method, DOES NOT query the database to find the actual primary key in use right now
160
+ # if no explicit primary key set, returns the default_defined_primary_key
161
+ def _defined_primary_key
162
+ if defined?(@primary_key)
163
+ @primary_key&.to_s
164
+ end || _default_defined_primary_key
165
+ end
166
+
167
+ private
168
+
169
+ # if this is a derived class, returns the base class's _defined_primary_key
170
+ # otherwise, returns 'id'
171
+ def _default_defined_primary_key
172
+ if self == base_class
173
+ 'id'
174
+ else
175
+ base_class._defined_primary_key
176
+ end
177
+ end
178
+
179
+ def _rails_default_primary_key
180
+ ::DeclareSchema::Model::IndexDefinition.new(self, [_defined_primary_key.to_sym], unique: true, name: DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME)
181
+ end
182
+
160
183
  # Declares the "foo_type" field that accompanies the "foo_id"
161
184
  # field for a polymorphic belongs_to
162
- def declare_polymorphic_type_field(foreign_type, column_options)
185
+ def _declare_polymorphic_type_field(foreign_type, column_options)
163
186
  declare_field(foreign_type, :string, column_options.merge(limit: 255))
164
187
  # FIXME: Before declare_schema was extracted, this used to now do:
165
188
  # never_show(type_col)
166
189
  # That needs doing somewhere
167
190
  end
168
191
 
169
- # Declare a rich-type for any attribute (i.e. getter method). This
170
- # does not effect the attribute in any way - it just records the
171
- # metadata.
172
- def declare_attr_type(name, type, options = {})
173
- attr_types[name] = klass = DeclareSchema.to_class(type)
174
- klass.try(:declared, self, name, options)
175
- end
176
-
177
192
  # Add field validations according to arguments in the
178
193
  # field declaration
179
- def add_validations_for_field(name, type, args, options)
194
+ def _add_validations_for_field(name, type, args, options)
180
195
  validates_presence_of name if :required.in?(args)
181
196
  validates_uniqueness_of name, allow_nil: !:required.in?(args) if :unique.in?(args)
182
197
 
@@ -195,18 +210,18 @@ module DeclareSchema
195
210
  end
196
211
  end
197
212
 
198
- def add_serialize_for_field(name, type, options)
213
+ def _add_serialize_for_field(name, type, options)
199
214
  if (serialize_class = options.delete(:serialize))
200
215
  type == :string || type == :text or raise ArgumentError, "serialize field type must be :string or :text"
201
216
  serialize_args = Array((serialize_class unless serialize_class == true))
202
217
  serialize(name, *serialize_args)
203
218
  if options.has_key?(:default)
204
- options[:default] = serialized_default(name, serialize_class == true ? Object : serialize_class, options[:default])
219
+ options[:default] = _serialized_default(name, serialize_class == true ? Object : serialize_class, options[:default])
205
220
  end
206
221
  end
207
222
  end
208
223
 
209
- def serialized_default(attr_name, class_name_or_coder, default)
224
+ def _serialized_default(attr_name, class_name_or_coder, default)
210
225
  # copied from https://github.com/rails/rails/blob/7d6cb950e7c0e31c2faaed08c81743439156c9f5/activerecord/lib/active_record/attribute_methods/serialization.rb#L70-L76
211
226
  coder = if class_name_or_coder == ::JSON
212
227
  ActiveRecord::Coders::JSON
@@ -225,7 +240,7 @@ module DeclareSchema
225
240
  end
226
241
  end
227
242
 
228
- def add_formatting_for_field(name, type)
243
+ def _add_formatting_for_field(name, type)
229
244
  if (type_class = DeclareSchema.to_class(type))
230
245
  if "format".in?(type_class.instance_methods)
231
246
  before_validation do |record|
@@ -235,7 +250,7 @@ module DeclareSchema
235
250
  end
236
251
  end
237
252
 
238
- def add_index_for_field(name, args, options)
253
+ def _add_index_for_field(name, args, options)
239
254
  if (to_name = options.delete(:index))
240
255
  index_opts =
241
256
  {
@@ -264,13 +279,13 @@ module DeclareSchema
264
279
  refl
265
280
  end
266
281
  end ||
267
- if (col = column(name.to_s))
282
+ if (col = _column(name.to_s))
268
283
  DeclareSchema::PLAIN_TYPES[col.type] || col.klass
269
284
  end
270
285
  end
271
286
 
272
287
  # Return the entry from #columns for the named column
273
- def column(name)
288
+ def _column(name)
274
289
  defined?(@table_exists) or @table_exists = table_exists?
275
290
  if @table_exists
276
291
  columns_hash[name.to_s]
@@ -8,7 +8,7 @@ module DeclareSchema
8
8
  class Column
9
9
  class << self
10
10
  def native_type?(type)
11
- type != :primary_key && native_types[type]
11
+ type != :primary_key && (native_types.empty? || native_types[type]) # empty will happen with NullDBAdapter used in assets:precompile
12
12
  end
13
13
 
14
14
  # MySQL example:
@@ -44,6 +44,8 @@ module DeclareSchema
44
44
  if ActiveRecord::Base.connection.class.name.match?(/mysql/i)
45
45
  types[:text][:limit] ||= 0xffff
46
46
  types[:binary][:limit] ||= 0xffff
47
+
48
+ types[:varbinary] ||= { name: "varbinary" } # TODO: :varbinary is an Invoca addition to Rails; make it a configurable option
47
49
  end
48
50
  end
49
51
  end
@@ -47,11 +47,9 @@ module DeclareSchema
47
47
  end
48
48
 
49
49
  def initialize(model, name, type, position: 0, **options)
50
- # TODO: TECH-5116
51
- # Invoca change - searching for the primary key was causing an additional database read on every model load. Assume
52
- # "id" which works for invoca.
53
- # raise ArgumentError, "you cannot provide a field spec for the primary key" if name == model.primary_key
54
- name == "id" and raise ArgumentError, "you cannot provide a field spec for the primary key"
50
+ _defined_primary_key = model._defined_primary_key
51
+
52
+ name.to_s == _defined_primary_key and raise ArgumentError, "you may not provide a field spec for the primary key #{name.inspect}"
55
53
 
56
54
  @model = model
57
55
  @name = name.to_sym
@@ -80,7 +78,7 @@ module DeclareSchema
80
78
  Column.native_type?(@type) or raise UnknownTypeError, "#{@type.inspect} not found in #{Column.native_types.inspect} for adapter #{ActiveRecord::Base.connection.class.name}"
81
79
 
82
80
  if @type.in?([:string, :text, :binary, :varbinary, :integer, :enum])
83
- @options[:limit] ||= Column.native_types[@type][:limit]
81
+ @options[:limit] ||= Column.native_types.dig(@type, :limit)
84
82
  else
85
83
  @type != :decimal && @options.has_key?(:limit) and warn("unsupported limit: for SQL type #{@type} in field #{model}##{@name}")
86
84
  @options.delete(:limit)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'index_definition'
4
+
3
5
  module DeclareSchema
4
6
  module Model
5
7
  class ForeignKeyDefinition
@@ -15,10 +17,10 @@ module DeclareSchema
15
17
  @child_table = model.table_name # unless a table rename, which would happen when a class is renamed??
16
18
  @parent_table_name = options[:parent_table]&.to_s
17
19
  @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)
19
20
 
20
- # Empty constraint lets mysql generate the name
21
- @constraint_name = options[:constraint_name]&.to_s || @index_name&.to_s || ''
21
+ @constraint_name = options[:constraint_name]&.to_s ||
22
+ options[:index_name]&.to_s ||
23
+ IndexDefinition.index_name(@foreign_key_name)
22
24
  @on_delete_cascade = options[:dependent] == :delete
23
25
  end
24
26
 
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeclareSchema
4
+ module Model
5
+ class HabtmModelShim
6
+ class << self
7
+ def from_reflection(refl)
8
+ join_table = refl.join_table
9
+ foreign_keys_and_classes = [
10
+ [refl.foreign_key.to_s, refl.active_record],
11
+ [refl.association_foreign_key.to_s, refl.class_name.constantize]
12
+ ].sort { |a, b| a.first <=> b.first }
13
+ foreign_keys = foreign_keys_and_classes.map(&:first)
14
+ foreign_key_classes = foreign_keys_and_classes.map(&:last)
15
+ # this may fail in weird ways if HABTM is running across two DB connections (assuming that's even supported)
16
+ # figure that anybody who sets THAT up can deal with their own migrations...
17
+ connection = refl.active_record.connection
18
+
19
+ new(join_table, foreign_keys, foreign_key_classes, connection)
20
+ end
21
+ end
22
+
23
+ attr_reader :join_table, :foreign_keys, :foreign_key_classes, :connection
24
+
25
+ def initialize(join_table, foreign_keys, foreign_key_classes, connection)
26
+ @join_table = join_table
27
+ @foreign_keys = foreign_keys
28
+ @foreign_key_classes = foreign_key_classes
29
+ @connection = connection
30
+ end
31
+
32
+ def table_options
33
+ {}
34
+ end
35
+
36
+ def table_name
37
+ join_table
38
+ end
39
+
40
+ def field_specs
41
+ foreign_keys.each_with_index.each_with_object({}) do |(v, position), result|
42
+ result[v] = ::DeclareSchema::Model::FieldSpec.new(self, v, :integer, position: position, null: false)
43
+ end
44
+ end
45
+
46
+ def primary_key
47
+ false # no single-column primary key in database
48
+ end
49
+
50
+ def _defined_primary_key
51
+ false # no single-column primary key declared
52
+ end
53
+
54
+ def index_definitions_with_primary_key
55
+ [
56
+ IndexDefinition.new(self, foreign_keys, unique: true, name: ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME),
57
+ IndexDefinition.new(self, foreign_keys.last) # not unique by itself; combines with primary key to be unique
58
+ ]
59
+ end
60
+
61
+ alias_method :index_definitions, :index_definitions_with_primary_key
62
+
63
+ def ignore_indexes
64
+ []
65
+ end
66
+
67
+ def constraint_specs
68
+ [
69
+ ForeignKeyDefinition.new(self, foreign_keys.first, parent_table: foreign_key_classes.first.table_name, constraint_name: "#{join_table}_FK1", dependent: :delete),
70
+ ForeignKeyDefinition.new(self, foreign_keys.last, parent_table: foreign_key_classes.last.table_name, constraint_name: "#{join_table}_FK2", dependent: :delete)
71
+ ]
72
+ end
73
+ end
74
+ end
75
+ end
@@ -19,7 +19,7 @@ module DeclareSchema
19
19
  @table = options.delete(:table_name) || model.table_name
20
20
  @fields = Array.wrap(fields).map(&:to_s)
21
21
  @explicit_name = options[:name] unless options.delete(:allow_equivalent)
22
- @name = options.delete(:name) || model.connection.index_name(table, column: @fields).gsub(/index.*_on_/, 'on_')
22
+ @name = options.delete(:name) || self.class.index_name(@fields)
23
23
  @unique = options.delete(:unique) || name == PRIMARY_KEY_NAME || false
24
24
 
25
25
  if @name.length > MYSQL_INDEX_NAME_MAX_LENGTH
@@ -60,6 +60,10 @@ module DeclareSchema
60
60
  index_definitions
61
61
  end
62
62
 
63
+ def index_name(columns)
64
+ "on_#{Array(columns).join("_and_")}"
65
+ end
66
+
63
67
  private
64
68
 
65
69
  # This is the old approach which is still needed for MySQL in Rails 4 and SQLite
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeclareSchema
4
- VERSION = "0.8.0.pre.2"
4
+ VERSION = "0.8.0"
5
5
  end
@@ -6,69 +6,6 @@ require 'active_record/connection_adapters/abstract_adapter'
6
6
  module Generators
7
7
  module DeclareSchema
8
8
  module Migration
9
- HabtmModelShim = Struct.new(:join_table, :foreign_keys, :foreign_key_classes, :connection) do
10
- class << self
11
- def from_reflection(refl)
12
- join_table = refl.join_table
13
- foreign_keys_and_classes = [
14
- [refl.foreign_key.to_s, refl.active_record],
15
- [refl.association_foreign_key.to_s, refl.class_name.constantize]
16
- ].sort { |a, b| a.first <=> b.first }
17
- foreign_keys = foreign_keys_and_classes.map(&:first)
18
- foreign_key_classes = foreign_keys_and_classes.map(&:last)
19
- # this may fail in weird ways if HABTM is running across two DB connections (assuming that's even supported)
20
- # figure that anybody who sets THAT up can deal with their own migrations...
21
- connection = refl.active_record.connection
22
-
23
- new(join_table, foreign_keys, foreign_key_classes, connection)
24
- end
25
- end
26
-
27
- def table_options
28
- {}
29
- end
30
-
31
- def table_name
32
- join_table
33
- end
34
-
35
- def table_exists?
36
- ActiveRecord::Migration.table_exists? table_name
37
- end
38
-
39
- def field_specs
40
- i = 0
41
- foreign_keys.each_with_object({}) do |v, result|
42
- result[v] = ::DeclareSchema::Model::FieldSpec.new(self, v, :integer, position: i, null: false)
43
- i += 1
44
- end
45
- end
46
-
47
- def primary_key
48
- false # no single-column primary key
49
- end
50
-
51
- def index_definitions_with_primary_key
52
- [
53
- ::DeclareSchema::Model::IndexDefinition.new(self, foreign_keys, unique: true, name: ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME),
54
- ::DeclareSchema::Model::IndexDefinition.new(self, foreign_keys.last) # not unique by itself; combines with primary key to be unique
55
- ]
56
- end
57
-
58
- alias_method :index_definitions, :index_definitions_with_primary_key
59
-
60
- def ignore_indexes
61
- []
62
- end
63
-
64
- def constraint_specs
65
- [
66
- ::DeclareSchema::Model::ForeignKeyDefinition.new(self, foreign_keys.first, parent_table: foreign_key_classes.first.table_name, constraint_name: "#{join_table}_FK1", dependent: :delete),
67
- ::DeclareSchema::Model::ForeignKeyDefinition.new(self, foreign_keys.last, parent_table: foreign_key_classes.last.table_name, constraint_name: "#{join_table}_FK2", dependent: :delete)
68
- ]
69
- end
70
- end
71
-
72
9
  class Migrator
73
10
  class Error < RuntimeError; end
74
11
 
@@ -266,7 +203,7 @@ module Generators
266
203
  end
267
204
  # generate shims for HABTM models
268
205
  habtm_tables.each do |name, refls|
269
- models_by_table_name[name] = HabtmModelShim.from_reflection(refls.first)
206
+ models_by_table_name[name] = ::DeclareSchema::Model::HabtmModelShim.from_reflection(refls.first)
270
207
  end
271
208
  model_table_names = models_by_table_name.keys
272
209
 
@@ -348,12 +285,13 @@ module Generators
348
285
  end
349
286
 
350
287
  def create_table_options(model, disable_auto_increment)
351
- if model.primary_key.blank? || disable_auto_increment
288
+ primary_key = model._defined_primary_key
289
+ if primary_key.blank? || disable_auto_increment
352
290
  "id: false"
353
- elsif model.primary_key == "id"
291
+ elsif primary_key == "id"
354
292
  "id: :bigint"
355
293
  else
356
- "primary_key: :#{model.primary_key}"
294
+ "primary_key: :#{primary_key}"
357
295
  end
358
296
  end
359
297
 
@@ -386,18 +324,18 @@ module Generators
386
324
  new_table_name = model.table_name
387
325
 
388
326
  db_columns = model.connection.columns(current_table_name).index_by(&:name)
389
- key_missing = db_columns[model.primary_key].nil? && model.primary_key.present?
390
- if model.primary_key.present?
391
- db_columns.delete(model.primary_key)
327
+ key_missing = db_columns[model._defined_primary_key].nil? && model._defined_primary_key.present?
328
+ if model._defined_primary_key.present?
329
+ db_columns.delete(model._defined_primary_key)
392
330
  end
393
331
 
394
332
  model_column_names = model.field_specs.keys.map(&:to_s)
395
333
  db_column_names = db_columns.keys.map(&:to_s)
396
334
 
397
335
  to_add = model_column_names - db_column_names
398
- to_add += [model.primary_key] if key_missing && model.primary_key.present?
336
+ to_add += [model._defined_primary_key] if key_missing && model._defined_primary_key.present?
399
337
  to_remove = db_column_names - model_column_names
400
- to_remove -= [model.primary_key.to_sym] if model.primary_key.present?
338
+ to_remove -= [model._defined_primary_key.to_sym] if model._defined_primary_key.present?
401
339
 
402
340
  to_rename = extract_column_renames!(to_add, to_remove, new_table_name)
403
341
 
@@ -6,7 +6,7 @@ rescue LoadError
6
6
  end
7
7
 
8
8
  RSpec.describe DeclareSchema::Model::FieldSpec do
9
- let(:model) { double('model', table_options: {}) }
9
+ let(:model) { double('model', table_options: {}, _defined_primary_key: 'id') }
10
10
  let(:col_spec) { double('col_spec', type: :string) }
11
11
 
12
12
  before do
@@ -83,37 +83,46 @@ RSpec.describe DeclareSchema::Model::FieldSpec do
83
83
  expect(subject.schema_attributes(col_spec)).to eq(type: :text, null: true, default: 'none')
84
84
  end
85
85
  end
86
+ end
86
87
 
87
- describe 'decimal' do
88
- it 'allows precision: and scale:' do
89
- subject = described_class.new(model, :quantity, :decimal, precision: 8, scale: 10, null: true, position: 3)
90
- expect(subject.schema_attributes(col_spec)).to eq(type: :decimal, precision: 8, scale: 10, null: true)
88
+ if defined?(Mysql2)
89
+ describe 'varbinary' do # TODO: :varbinary is an Invoca addition to Rails; make it a configurable option
90
+ it 'is supported' do
91
+ subject = described_class.new(model, :binary_dump, :varbinary, limit: 200, null: false, position: 2)
92
+ expect(subject.schema_attributes(col_spec)).to eq(type: :varbinary, limit: 200, null: false)
91
93
  end
94
+ end
95
+ end
92
96
 
93
- it 'requires precision:' do
94
- expect_any_instance_of(described_class).to receive(:warn).with(/precision: required for :decimal type/)
95
- described_class.new(model, :quantity, :decimal, scale: 10, null: true, position: 3)
96
- end
97
+ describe 'decimal' do
98
+ it 'allows precision: and scale:' do
99
+ subject = described_class.new(model, :quantity, :decimal, precision: 8, scale: 10, null: true, position: 3)
100
+ expect(subject.schema_attributes(col_spec)).to eq(type: :decimal, precision: 8, scale: 10, null: true)
101
+ end
97
102
 
98
- it 'requires scale:' do
99
- expect_any_instance_of(described_class).to receive(:warn).with(/scale: required for :decimal type/)
100
- described_class.new(model, :quantity, :decimal, precision: 8, null: true, position: 3)
101
- end
103
+ it 'requires precision:' do
104
+ expect_any_instance_of(described_class).to receive(:warn).with(/precision: required for :decimal type/)
105
+ described_class.new(model, :quantity, :decimal, scale: 10, null: true, position: 3)
106
+ end
107
+
108
+ it 'requires scale:' do
109
+ expect_any_instance_of(described_class).to receive(:warn).with(/scale: required for :decimal type/)
110
+ described_class.new(model, :quantity, :decimal, precision: 8, null: true, position: 3)
102
111
  end
112
+ end
103
113
 
104
- [:integer, :bigint, :string, :text, :binary, :datetime, :date, :time].each do |t|
105
- describe t.to_s do
106
- let(:extra) { t == :string ? { limit: 100 } : {} }
114
+ [:integer, :bigint, :string, :text, :binary, :datetime, :date, :time, (:varbinary if defined?(Mysql2))].compact.each do |t|
115
+ describe t.to_s do
116
+ let(:extra) { t == :string ? { limit: 100 } : {} }
107
117
 
108
- it 'does not allow precision:' do
109
- expect_any_instance_of(described_class).to receive(:warn).with(/precision: only allowed for :decimal type/)
110
- described_class.new(model, :quantity, t, { precision: 8, null: true, position: 3 }.merge(extra))
111
- end unless t == :datetime
118
+ it 'does not allow precision:' do
119
+ expect_any_instance_of(described_class).to receive(:warn).with(/precision: only allowed for :decimal type/)
120
+ described_class.new(model, :quantity, t, { precision: 8, null: true, position: 3 }.merge(extra))
121
+ end unless t == :datetime
112
122
 
113
- it 'does not allow scale:' do
114
- expect_any_instance_of(described_class).to receive(:warn).with(/scale: only allowed for :decimal type/)
115
- described_class.new(model, :quantity, t, { scale: 10, null: true, position: 3 }.merge(extra))
116
- end
123
+ it 'does not allow scale:' do
124
+ expect_any_instance_of(described_class).to receive(:warn).with(/scale: only allowed for :decimal type/)
125
+ described_class.new(model, :quantity, t, { scale: 10, null: true, position: 3 }.merge(extra))
117
126
  end
118
127
  end
119
128
  end
@@ -19,7 +19,7 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
19
19
  end
20
20
 
21
21
  generate_migrations '-n', '-m'
22
- expect(Foo.primary_key).to eq('foo_id')
22
+ expect(Foo._defined_primary_key).to eq('foo_id')
23
23
 
24
24
  ### migrate from
25
25
  # rename from custom primary_key
@@ -31,7 +31,7 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
31
31
 
32
32
  puts "\n\e[45m Please enter 'id' (no quotes) at the next prompt \e[0m"
33
33
  generate_migrations '-n', '-m'
34
- expect(Foo.primary_key).to eq('id')
34
+ expect(Foo._defined_primary_key).to eq('id')
35
35
 
36
36
  nuke_model_class(Foo)
37
37
 
@@ -47,7 +47,7 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
47
47
 
48
48
  puts "\n\e[45m Please enter 'drop id' (no quotes) at the next prompt \e[0m"
49
49
  generate_migrations '-n', '-m'
50
- expect(Foo.primary_key).to eq('foo_id')
50
+ expect(Foo._defined_primary_key).to eq('foo_id')
51
51
 
52
52
  ### ensure it doesn't cause further migrations
53
53
 
@@ -372,14 +372,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
372
372
 
373
373
  add_index :adverts, [:category_id], name: 'on_category_id'
374
374
 
375
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" if defined?(Mysql2)}
375
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" if defined?(Mysql2)}
376
376
  EOS
377
377
  .and migrate_down(<<~EOS.strip)
378
378
  remove_column :adverts, :category_id
379
379
 
380
380
  remove_index :adverts, name: :on_category_id rescue ActiveRecord::StatementInvalid
381
381
 
382
- #{"remove_foreign_key(\"adverts\", name: \"index_adverts_on_category_id\")\n" if defined?(Mysql2)}
382
+ #{"remove_foreign_key(\"adverts\", name: \"on_category_id\")\n" if defined?(Mysql2)}
383
383
  EOS
384
384
  )
385
385
 
@@ -400,8 +400,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
400
400
 
401
401
  add_index :adverts, [:c_id], name: 'on_c_id'
402
402
 
403
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
404
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
403
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
404
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
405
405
  EOS
406
406
  )
407
407
 
@@ -420,8 +420,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
420
420
  migrate_up(<<~EOS.strip)
421
421
  add_column :adverts, :category_id, :integer, limit: 8, null: false
422
422
 
423
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
424
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
423
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
424
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
425
425
  EOS
426
426
  )
427
427
 
@@ -442,8 +442,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
442
442
 
443
443
  add_index :adverts, [:category_id], name: 'my_index'
444
444
 
445
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
446
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
445
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
446
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
447
447
  EOS
448
448
  )
449
449
 
@@ -468,16 +468,16 @@ RSpec.describe 'DeclareSchema Migration Generator' do
468
468
  add_column :adverts, :updated_at, :datetime, null: true
469
469
  add_column :adverts, :lock_version, :integer#{lock_version_limit}, null: false, default: 1
470
470
 
471
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
472
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
471
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
472
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
473
473
  EOS
474
474
  .and migrate_down(<<~EOS.strip)
475
475
  remove_column :adverts, :created_at
476
476
  remove_column :adverts, :updated_at
477
477
  remove_column :adverts, :lock_version
478
478
 
479
- #{"remove_foreign_key(\"adverts\", name: \"index_adverts_on_category_id\")\n" +
480
- "remove_foreign_key(\"adverts\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
479
+ #{"remove_foreign_key(\"adverts\", name: \"on_category_id\")\n" +
480
+ "remove_foreign_key(\"adverts\", name: \"on_c_id\")" if defined?(Mysql2)}
481
481
  EOS
482
482
  )
483
483
 
@@ -501,8 +501,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
501
501
 
502
502
  add_index :adverts, [:title], name: 'on_title'
503
503
 
504
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
505
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
504
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
505
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
506
506
  EOS
507
507
  )
508
508
 
@@ -522,8 +522,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
522
522
 
523
523
  add_index :adverts, [:title], unique: true, name: 'on_title'
524
524
 
525
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
526
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
525
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
526
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
527
527
  EOS
528
528
  )
529
529
 
@@ -543,8 +543,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
543
543
 
544
544
  add_index :adverts, [:title], name: 'my_index'
545
545
 
546
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
547
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
546
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
547
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
548
548
  EOS
549
549
  )
550
550
 
@@ -562,8 +562,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
562
562
 
563
563
  add_index :adverts, [:title], name: 'on_title'
564
564
 
565
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
566
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
565
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
566
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
567
567
  EOS
568
568
  )
569
569
 
@@ -581,8 +581,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
581
581
 
582
582
  add_index :adverts, [:title], unique: true, name: 'my_index'
583
583
 
584
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
585
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
584
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
585
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
586
586
  EOS
587
587
  )
588
588
 
@@ -600,8 +600,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
600
600
 
601
601
  add_index :adverts, [:title, :category_id], name: 'on_title_and_category_id'
602
602
 
603
- #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
604
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")" if defined?(Mysql2)}
603
+ #{"add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
604
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")" if defined?(Mysql2)}
605
605
  EOS
606
606
  )
607
607
 
@@ -637,8 +637,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
637
637
  "add_index :ads, [:id], unique: true, name: 'PRIMARY'\n"
638
638
  elsif defined?(Mysql2)
639
639
  "execute \"ALTER TABLE ads DROP PRIMARY KEY, ADD PRIMARY KEY (id)\"\n\n" +
640
- "add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"index_adverts_on_category_id\")\n" +
641
- "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"index_adverts_on_c_id\")"
640
+ "add_foreign_key(\"adverts\", \"categories\", column: \"category_id\", name: \"on_category_id\")\n" +
641
+ "add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"on_c_id\")"
642
642
  end}
643
643
  EOS
644
644
  .and migrate_down(<<~EOS.strip)
@@ -651,8 +651,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do
651
651
  "add_index :adverts, [:id], unique: true, name: 'PRIMARY'\n"
652
652
  elsif defined?(Mysql2)
653
653
  "execute \"ALTER TABLE adverts DROP PRIMARY KEY, ADD PRIMARY KEY (id)\"\n\n" +
654
- "remove_foreign_key(\"adverts\", name: \"index_adverts_on_category_id\")\n" +
655
- "remove_foreign_key(\"adverts\", name: \"index_adverts_on_c_id\")"
654
+ "remove_foreign_key(\"adverts\", name: \"on_category_id\")\n" +
655
+ "remove_foreign_key(\"adverts\", name: \"on_c_id\")"
656
656
  end}
657
657
  EOS
658
658
  )
@@ -37,6 +37,11 @@ RSpec.describe DeclareSchema::Model::Column do
37
37
  expect(described_class.native_type?(type)).to be_falsey
38
38
  end
39
39
  end
40
+
41
+ it "is truthy when there's a NullDbAdapter (like for assets:precompile) that doesn't have any native types" do
42
+ allow(described_class).to receive(:native_types).and_return({})
43
+ expect(described_class.native_type?(:integer)).to be_truthy
44
+ end
40
45
  end
41
46
 
42
47
  describe '.native_types' do
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+
5
+ begin
6
+ require 'mysql2'
7
+ rescue LoadError
8
+ end
9
+
10
+ require_relative '../../../../lib/declare_schema/model/habtm_model_shim'
11
+
12
+ RSpec.describe DeclareSchema::Model::HabtmModelShim do
13
+ let(:join_table) { "parent_1_parent_2" }
14
+ let(:foreign_keys) { ["parent_1_id", "parent_2_id"] }
15
+ let(:foreign_key_classes) { [Parent1, Parent2] }
16
+
17
+ before do
18
+ load File.expand_path('../prepare_testapp.rb', __dir__)
19
+
20
+ class Parent1 < ActiveRecord::Base
21
+ self.table_name = "parent_1s"
22
+ end
23
+
24
+ class Parent2 < ActiveRecord::Base
25
+ self.table_name = "parent_2s"
26
+ end
27
+ end
28
+
29
+ describe 'class methods' do
30
+ describe '.from_reflection' do
31
+ let(:reflection) { double("reflection", join_table: join_table,
32
+ foreign_key: foreign_keys.first,
33
+ association_foreign_key: foreign_keys.last,
34
+ active_record: foreign_key_classes.first,
35
+ class_name: 'Parent1') }
36
+ it 'returns a new object' do
37
+ result = described_class.from_reflection(reflection)
38
+
39
+ expect(result).to be_a(described_class)
40
+ end
41
+ end
42
+ end
43
+
44
+ describe 'instance methods' do
45
+ let(:connection) { instance_double(ActiveRecord::Base.connection.class, "connection") }
46
+
47
+ subject { described_class.new(join_table, foreign_keys, foreign_key_classes, connection) }
48
+
49
+ describe '#initialize' do
50
+ it 'stores initialization attributes' do
51
+ expect(subject.join_table).to eq(join_table)
52
+ expect(subject.foreign_keys).to eq(foreign_keys)
53
+ expect(subject.foreign_key_classes).to be(foreign_key_classes)
54
+ expect(subject.connection).to be(connection)
55
+ end
56
+ end
57
+
58
+ describe '#table_options' do
59
+ it 'returns empty hash' do
60
+ expect(subject.table_options).to eq({})
61
+ end
62
+ end
63
+
64
+ describe '#table_name' do
65
+ it 'returns join_table' do
66
+ expect(subject.table_name).to eq(join_table)
67
+ end
68
+ end
69
+
70
+ describe '#field_specs' do
71
+ it 'returns 2 field specs' do
72
+ result = subject.field_specs
73
+ expect(result.size).to eq(2), result.inspect
74
+
75
+ expect(result[foreign_keys.first]).to be_a(::DeclareSchema::Model::FieldSpec)
76
+ expect(result[foreign_keys.first].model).to eq(subject)
77
+ expect(result[foreign_keys.first].name.to_s).to eq(foreign_keys.first)
78
+ expect(result[foreign_keys.first].type).to eq(:integer)
79
+ expect(result[foreign_keys.first].position).to eq(0)
80
+
81
+ expect(result[foreign_keys.last]).to be_a(::DeclareSchema::Model::FieldSpec)
82
+ expect(result[foreign_keys.last].model).to eq(subject)
83
+ expect(result[foreign_keys.last].name.to_s).to eq(foreign_keys.last)
84
+ expect(result[foreign_keys.last].type).to eq(:integer)
85
+ expect(result[foreign_keys.last].position).to eq(1)
86
+ end
87
+ end
88
+
89
+ describe '#primary_key' do
90
+ it 'returns false' do
91
+ expect(subject._defined_primary_key).to eq(false)
92
+ end
93
+ end
94
+
95
+ describe '#_defined_primary_key' do
96
+ it 'returns false' do
97
+ expect(subject._defined_primary_key).to eq(false)
98
+ end
99
+ end
100
+
101
+ describe '#index_definitions_with_primary_key' do
102
+ it 'returns 2 index definitions' do
103
+ result = subject.index_definitions_with_primary_key
104
+ expect(result.size).to eq(2), result.inspect
105
+
106
+ expect(result.first).to be_a(::DeclareSchema::Model::IndexDefinition)
107
+ expect(result.first.name).to eq('PRIMARY')
108
+ expect(result.first.fields).to eq(['parent_1_id', 'parent_2_id'])
109
+ expect(result.first.unique).to be_truthy
110
+
111
+ expect(result.last).to be_a(::DeclareSchema::Model::IndexDefinition)
112
+ expect(result.last.name).to eq('on_parent_2_id')
113
+ expect(result.last.unique).to be_falsey
114
+ expect(result.last.fields).to eq(['parent_2_id'])
115
+ end
116
+ end
117
+
118
+ describe '#index_definitions' do
119
+ it 'returns index_definitions_with_primary_key' do
120
+ result = subject.index_definitions
121
+ expect(result.size).to eq(2), result.inspect
122
+ end
123
+ end
124
+
125
+ describe 'ignore_indexes' do
126
+ it 'returns empty array' do
127
+ expect(subject.ignore_indexes).to eq([])
128
+ end
129
+ end
130
+
131
+ describe '#constraint_specs' do
132
+ it 'returns 2 foreign keys' do
133
+ result = subject.constraint_specs
134
+ expect(result.size).to eq(2), result.inspect
135
+
136
+ expect(result.first).to be_a(::DeclareSchema::Model::ForeignKeyDefinition)
137
+ expect(result.first.foreign_key).to eq(foreign_keys.first)
138
+ expect(result.first.parent_table_name).to be(Parent1.table_name)
139
+ expect(result.first.on_delete_cascade).to be_truthy
140
+
141
+ expect(result.last).to be_a(::DeclareSchema::Model::ForeignKeyDefinition)
142
+ expect(result.last.foreign_key).to eq(foreign_keys.last)
143
+ expect(result.last.parent_table_name).to be(Parent2.table_name)
144
+ expect(result.last.on_delete_cascade).to be_truthy
145
+ end
146
+ end
147
+ end
148
+ end
@@ -58,7 +58,17 @@ RSpec.describe DeclareSchema::Model::IndexDefinition do
58
58
  end
59
59
  end
60
60
 
61
- describe 'class << self' do
61
+ describe 'class methods' do
62
+ describe 'index_name' do
63
+ it 'works with a single column' do
64
+ expect(described_class.index_name('parent_id')).to eq('on_parent_id')
65
+ end
66
+
67
+ it 'works with many columns' do
68
+ expect(described_class.index_name(['a', 'b', 'c'])).to eq('on_a_and_b_and_c')
69
+ end
70
+ end
71
+
62
72
  context 'with a migrated database' do
63
73
  before do
64
74
  ActiveRecord::Base.connection.execute <<~EOS
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.8.0.pre.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca Development adapted from hobo_fields by Tom Locke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-18 00:00:00.000000000 Z
11
+ date: 2021-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -64,6 +64,7 @@ files:
64
64
  - lib/declare_schema/model/column.rb
65
65
  - lib/declare_schema/model/field_spec.rb
66
66
  - lib/declare_schema/model/foreign_key_definition.rb
67
+ - lib/declare_schema/model/habtm_model_shim.rb
67
68
  - lib/declare_schema/model/index_definition.rb
68
69
  - lib/declare_schema/model/table_options_definition.rb
69
70
  - lib/declare_schema/railtie.rb
@@ -85,6 +86,7 @@ files:
85
86
  - spec/lib/declare_schema/migration_generator_spec.rb
86
87
  - spec/lib/declare_schema/model/column_spec.rb
87
88
  - spec/lib/declare_schema/model/foreign_key_definition_spec.rb
89
+ - spec/lib/declare_schema/model/habtm_model_shim_spec.rb
88
90
  - spec/lib/declare_schema/model/index_definition_spec.rb
89
91
  - spec/lib/declare_schema/model/table_options_definition_spec.rb
90
92
  - spec/lib/declare_schema/prepare_testapp.rb