declare_schema 0.7.0 → 0.8.0.pre.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 +4 -4
- data/CHANGELOG.md +16 -3
- data/Gemfile.lock +51 -49
- data/lib/declare_schema/field_declaration_dsl.rb +3 -4
- data/lib/declare_schema/model.rb +26 -4
- data/lib/declare_schema/model/column.rb +34 -44
- data/lib/declare_schema/model/field_spec.rb +19 -22
- data/lib/declare_schema/model/foreign_key_definition.rb +5 -3
- data/lib/declare_schema/model/habtm_model_shim.rb +75 -0
- data/lib/declare_schema/model/index_definition.rb +5 -1
- data/lib/declare_schema/version.rb +1 -1
- data/lib/generators/declare_schema/migration/migration_generator.rb +1 -1
- data/lib/generators/declare_schema/migration/migrator.rb +8 -71
- data/spec/lib/declare_schema/field_spec_spec.rb +18 -5
- data/spec/lib/declare_schema/migration_generator_spec.rb +28 -28
- data/spec/lib/declare_schema/model/column_spec.rb +10 -24
- data/spec/lib/declare_schema/model/habtm_model_shim_spec.rb +148 -0
- data/spec/lib/declare_schema/model/index_definition_spec.rb +11 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 296c7533718469d744f10a412c4a65b8da22ab1509a795fba4a3345fecfe2d99
|
|
4
|
+
data.tar.gz: cf6d5f65c95191a1e7976feec5c5def7291aff7abb2b22a0c78fa1184865c1e7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c597b1b7d371ed218a36a6bd63bcb401a9c482b45e1b549a3ff0b18a1eefa9bef749de95804a9da4401a13e2e09178639942cd068ef0f4ec02f7c816b9175087
|
|
7
|
+
data.tar.gz: 1cc1dd96b29b84b9a1d2397db7fbbf68bb72ec1c471d6a029a786906f3e402336db17e5f8af910ca36d54cdd6c3eb652d8a18ebf149cdb87719437fd0011c06c
|
data/CHANGELOG.md
CHANGED
|
@@ -4,16 +4,27 @@ 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.
|
|
7
|
+
## [0.8.0] - UNRELEASED
|
|
8
|
+
### Removed
|
|
9
|
+
- Removed `sql_type` that was confusing because it was actually the same as `type` (ex: :string) and not
|
|
10
|
+
in fact the SQL type (ex: ``varchar(255)'`).
|
|
11
|
+
|
|
12
|
+
## [0.7.1] - 2021-02-17
|
|
13
|
+
### Fixed
|
|
14
|
+
- Exclude unknown options from FieldSpec#sql_options and #schema_attributes.
|
|
15
|
+
- Fixed a bug where fk_field_options were getting merged into spec_attrs after checking for equivalence,
|
|
16
|
+
leading to phantom migrations with no changes, or missing migrations when just the fk_field_options changed.
|
|
17
|
+
|
|
18
|
+
## [0.7.0] - 2021-02-14
|
|
8
19
|
### Changed
|
|
9
20
|
- Use `schema_attributes` for generating both up and down change migrations, so they are guaranteed to be symmetrical.
|
|
10
21
|
Note: Rails schema dumper is still used for the down migration to replace a model that has been dropped.
|
|
11
22
|
|
|
12
|
-
## [0.6.4] -
|
|
23
|
+
## [0.6.4] - 2021-02-08
|
|
13
24
|
- Fixed a bug where the generated call to add_foreign_key() was not setting `column:`,
|
|
14
25
|
so it only worked in cases where Rails could infer the foreign key by convention.
|
|
15
26
|
|
|
16
|
-
## [0.6.3] -
|
|
27
|
+
## [0.6.3] - 2021-01-21
|
|
17
28
|
### Added
|
|
18
29
|
- Added `add_foreign_key` native rails call in `DeclareSchema::Model::ForeignKeyDefinition#to_add_statement`.
|
|
19
30
|
|
|
@@ -119,6 +130,8 @@ using the appropriate Rails configuration attributes.
|
|
|
119
130
|
### Added
|
|
120
131
|
- Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
|
|
121
132
|
|
|
133
|
+
[0.8.0]: https://github.com/Invoca/declare_schema/compare/v0.7.1...v0.8.0
|
|
134
|
+
[0.7.1]: https://github.com/Invoca/declare_schema/compare/v0.7.0...v0.7.1
|
|
122
135
|
[0.7.0]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.7.0
|
|
123
136
|
[0.6.4]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.6.4
|
|
124
137
|
[0.6.3]: https://github.com/Invoca/declare_schema/compare/v0.6.2...v0.6.3
|
data/Gemfile.lock
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
declare_schema (0.
|
|
4
|
+
declare_schema (0.8.0.pre.4)
|
|
5
5
|
rails (>= 4.2)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
actioncable (5.2.4.
|
|
11
|
-
actionpack (= 5.2.4.
|
|
10
|
+
actioncable (5.2.4.5)
|
|
11
|
+
actionpack (= 5.2.4.5)
|
|
12
12
|
nio4r (~> 2.0)
|
|
13
13
|
websocket-driver (>= 0.6.1)
|
|
14
|
-
actionmailer (5.2.4.
|
|
15
|
-
actionpack (= 5.2.4.
|
|
16
|
-
actionview (= 5.2.4.
|
|
17
|
-
activejob (= 5.2.4.
|
|
14
|
+
actionmailer (5.2.4.5)
|
|
15
|
+
actionpack (= 5.2.4.5)
|
|
16
|
+
actionview (= 5.2.4.5)
|
|
17
|
+
activejob (= 5.2.4.5)
|
|
18
18
|
mail (~> 2.5, >= 2.5.4)
|
|
19
19
|
rails-dom-testing (~> 2.0)
|
|
20
|
-
actionpack (5.2.4.
|
|
21
|
-
actionview (= 5.2.4.
|
|
22
|
-
activesupport (= 5.2.4.
|
|
20
|
+
actionpack (5.2.4.5)
|
|
21
|
+
actionview (= 5.2.4.5)
|
|
22
|
+
activesupport (= 5.2.4.5)
|
|
23
23
|
rack (~> 2.0, >= 2.0.8)
|
|
24
24
|
rack-test (>= 0.6.3)
|
|
25
25
|
rails-dom-testing (~> 2.0)
|
|
26
26
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
27
|
-
actionview (5.2.4.
|
|
28
|
-
activesupport (= 5.2.4.
|
|
27
|
+
actionview (5.2.4.5)
|
|
28
|
+
activesupport (= 5.2.4.5)
|
|
29
29
|
builder (~> 3.1)
|
|
30
30
|
erubi (~> 1.4)
|
|
31
31
|
rails-dom-testing (~> 2.0)
|
|
32
32
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
33
|
-
activejob (5.2.4.
|
|
34
|
-
activesupport (= 5.2.4.
|
|
33
|
+
activejob (5.2.4.5)
|
|
34
|
+
activesupport (= 5.2.4.5)
|
|
35
35
|
globalid (>= 0.3.6)
|
|
36
|
-
activemodel (5.2.4.
|
|
37
|
-
activesupport (= 5.2.4.
|
|
38
|
-
activerecord (5.2.4.
|
|
39
|
-
activemodel (= 5.2.4.
|
|
40
|
-
activesupport (= 5.2.4.
|
|
36
|
+
activemodel (5.2.4.5)
|
|
37
|
+
activesupport (= 5.2.4.5)
|
|
38
|
+
activerecord (5.2.4.5)
|
|
39
|
+
activemodel (= 5.2.4.5)
|
|
40
|
+
activesupport (= 5.2.4.5)
|
|
41
41
|
arel (>= 9.0)
|
|
42
|
-
activestorage (5.2.4.
|
|
43
|
-
actionpack (= 5.2.4.
|
|
44
|
-
activerecord (= 5.2.4.
|
|
42
|
+
activestorage (5.2.4.5)
|
|
43
|
+
actionpack (= 5.2.4.5)
|
|
44
|
+
activerecord (= 5.2.4.5)
|
|
45
45
|
marcel (~> 0.3.1)
|
|
46
|
-
activesupport (5.2.4.
|
|
46
|
+
activesupport (5.2.4.5)
|
|
47
47
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
48
48
|
i18n (>= 0.7, < 2)
|
|
49
49
|
minitest (~> 5.1)
|
|
@@ -60,19 +60,19 @@ GEM
|
|
|
60
60
|
byebug (11.1.3)
|
|
61
61
|
climate_control (0.2.0)
|
|
62
62
|
coderay (1.1.3)
|
|
63
|
-
concurrent-ruby (1.1.
|
|
63
|
+
concurrent-ruby (1.1.8)
|
|
64
64
|
crass (1.0.6)
|
|
65
65
|
diff-lcs (1.4.4)
|
|
66
|
-
erubi (1.
|
|
66
|
+
erubi (1.10.0)
|
|
67
67
|
ffi (1.14.2)
|
|
68
68
|
globalid (0.4.2)
|
|
69
69
|
activesupport (>= 4.2.0)
|
|
70
|
-
i18n (1.8.
|
|
70
|
+
i18n (1.8.9)
|
|
71
71
|
concurrent-ruby (~> 1.0)
|
|
72
72
|
listen (3.4.1)
|
|
73
73
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
74
74
|
rb-inotify (~> 0.9, >= 0.9.10)
|
|
75
|
-
loofah (2.
|
|
75
|
+
loofah (2.9.0)
|
|
76
76
|
crass (~> 1.0.2)
|
|
77
77
|
nokogiri (>= 1.5.9)
|
|
78
78
|
mail (2.7.1)
|
|
@@ -82,12 +82,13 @@ GEM
|
|
|
82
82
|
method_source (1.0.0)
|
|
83
83
|
mimemagic (0.3.5)
|
|
84
84
|
mini_mime (1.0.2)
|
|
85
|
-
mini_portile2 (2.
|
|
86
|
-
minitest (5.14.
|
|
85
|
+
mini_portile2 (2.5.0)
|
|
86
|
+
minitest (5.14.3)
|
|
87
87
|
msgpack (1.4.2)
|
|
88
|
-
nio4r (2.5.
|
|
89
|
-
nokogiri (1.
|
|
90
|
-
mini_portile2 (~> 2.
|
|
88
|
+
nio4r (2.5.5)
|
|
89
|
+
nokogiri (1.11.1)
|
|
90
|
+
mini_portile2 (~> 2.5.0)
|
|
91
|
+
racc (~> 1.4)
|
|
91
92
|
parallel (1.19.2)
|
|
92
93
|
parser (2.7.1.4)
|
|
93
94
|
ast (~> 2.4.1)
|
|
@@ -97,35 +98,36 @@ GEM
|
|
|
97
98
|
pry-byebug (3.9.0)
|
|
98
99
|
byebug (~> 11.0)
|
|
99
100
|
pry (~> 0.13.0)
|
|
101
|
+
racc (1.5.2)
|
|
100
102
|
rack (2.2.3)
|
|
101
103
|
rack-test (1.1.0)
|
|
102
104
|
rack (>= 1.0, < 3)
|
|
103
|
-
rails (5.2.4.
|
|
104
|
-
actioncable (= 5.2.4.
|
|
105
|
-
actionmailer (= 5.2.4.
|
|
106
|
-
actionpack (= 5.2.4.
|
|
107
|
-
actionview (= 5.2.4.
|
|
108
|
-
activejob (= 5.2.4.
|
|
109
|
-
activemodel (= 5.2.4.
|
|
110
|
-
activerecord (= 5.2.4.
|
|
111
|
-
activestorage (= 5.2.4.
|
|
112
|
-
activesupport (= 5.2.4.
|
|
105
|
+
rails (5.2.4.5)
|
|
106
|
+
actioncable (= 5.2.4.5)
|
|
107
|
+
actionmailer (= 5.2.4.5)
|
|
108
|
+
actionpack (= 5.2.4.5)
|
|
109
|
+
actionview (= 5.2.4.5)
|
|
110
|
+
activejob (= 5.2.4.5)
|
|
111
|
+
activemodel (= 5.2.4.5)
|
|
112
|
+
activerecord (= 5.2.4.5)
|
|
113
|
+
activestorage (= 5.2.4.5)
|
|
114
|
+
activesupport (= 5.2.4.5)
|
|
113
115
|
bundler (>= 1.3.0)
|
|
114
|
-
railties (= 5.2.4.
|
|
116
|
+
railties (= 5.2.4.5)
|
|
115
117
|
sprockets-rails (>= 2.0.0)
|
|
116
118
|
rails-dom-testing (2.0.3)
|
|
117
119
|
activesupport (>= 4.2.0)
|
|
118
120
|
nokogiri (>= 1.6)
|
|
119
121
|
rails-html-sanitizer (1.3.0)
|
|
120
122
|
loofah (~> 2.3)
|
|
121
|
-
railties (5.2.4.
|
|
122
|
-
actionpack (= 5.2.4.
|
|
123
|
-
activesupport (= 5.2.4.
|
|
123
|
+
railties (5.2.4.5)
|
|
124
|
+
actionpack (= 5.2.4.5)
|
|
125
|
+
activesupport (= 5.2.4.5)
|
|
124
126
|
method_source
|
|
125
127
|
rake (>= 0.8.7)
|
|
126
128
|
thor (>= 0.19.0, < 2.0)
|
|
127
129
|
rainbow (3.0.0)
|
|
128
|
-
rake (13.0.
|
|
130
|
+
rake (13.0.3)
|
|
129
131
|
rb-fsevent (0.10.4)
|
|
130
132
|
rb-inotify (0.10.1)
|
|
131
133
|
ffi (~> 1.0)
|
|
@@ -167,9 +169,9 @@ GEM
|
|
|
167
169
|
activesupport (>= 4.0)
|
|
168
170
|
sprockets (>= 3.0.0)
|
|
169
171
|
sqlite3 (1.4.2)
|
|
170
|
-
thor (1.0
|
|
172
|
+
thor (1.1.0)
|
|
171
173
|
thread_safe (0.3.6)
|
|
172
|
-
tzinfo (1.2.
|
|
174
|
+
tzinfo (1.2.9)
|
|
173
175
|
thread_safe (~> 0.1)
|
|
174
176
|
unicode-display_width (1.7.0)
|
|
175
177
|
websocket-driver (0.7.3)
|
|
@@ -28,13 +28,12 @@ module DeclareSchema
|
|
|
28
28
|
field(:lock_version, :integer, default: 1, null: false)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
def field(name, type, *args)
|
|
32
|
-
|
|
33
|
-
@model.declare_field(name, type, *(args + [@options.merge(options)]))
|
|
31
|
+
def field(name, type, *args, **options)
|
|
32
|
+
@model.declare_field(name, type, *[*args, @options.merge(options)])
|
|
34
33
|
end
|
|
35
34
|
|
|
36
35
|
def method_missing(name, *args)
|
|
37
|
-
field(name,
|
|
36
|
+
field(name, *args)
|
|
38
37
|
end
|
|
39
38
|
end
|
|
40
39
|
end
|
data/lib/declare_schema/model.rb
CHANGED
|
@@ -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
|
|
@@ -81,8 +83,7 @@ module DeclareSchema
|
|
|
81
83
|
# arguments. The arguments are forwarded to the #field_added
|
|
82
84
|
# callback, allowing custom metadata to be added to field
|
|
83
85
|
# declarations.
|
|
84
|
-
def declare_field(name, type, *args)
|
|
85
|
-
options = args.extract_options!
|
|
86
|
+
def declare_field(name, type, *args, **options)
|
|
86
87
|
try(:field_added, name, type, args, options)
|
|
87
88
|
add_serialize_for_field(name, type, options)
|
|
88
89
|
add_formatting_for_field(name, type)
|
|
@@ -100,8 +101,29 @@ module DeclareSchema
|
|
|
100
101
|
end
|
|
101
102
|
end
|
|
102
103
|
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
if ::Rails::VERSION::MAJOR < 5
|
|
105
|
+
def primary_key
|
|
106
|
+
super || 'id'
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# returns the primary key (String) as declared with primary_key =
|
|
111
|
+
# unlike the `primary_key` method, DOES NOT query the database to find the actual primary key in use right now
|
|
112
|
+
# if no explicit primary key set, returns the default_defined_primary_key
|
|
113
|
+
def defined_primary_key
|
|
114
|
+
if defined?(@primary_key)
|
|
115
|
+
@primary_key&.to_s
|
|
116
|
+
end || default_defined_primary_key
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# if this is a derived class, returns the base class's defined_primary_key
|
|
120
|
+
# otherwise, returns 'id'
|
|
121
|
+
def default_defined_primary_key
|
|
122
|
+
if self == base_class
|
|
123
|
+
'id'
|
|
124
|
+
else
|
|
125
|
+
base_class.defined_primary_key
|
|
126
|
+
end
|
|
105
127
|
end
|
|
106
128
|
|
|
107
129
|
private
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module DeclareSchema
|
|
4
|
-
class
|
|
4
|
+
class UnknownTypeError < RuntimeError; end
|
|
5
5
|
|
|
6
6
|
module Model
|
|
7
7
|
# This class is a wrapper for the ActiveRecord::...::Column class
|
|
8
8
|
class Column
|
|
9
9
|
class << self
|
|
10
10
|
def native_type?(type)
|
|
11
|
-
type != :primary_key && native_types.
|
|
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:
|
|
@@ -48,69 +48,59 @@ module DeclareSchema
|
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
def
|
|
52
|
-
|
|
53
|
-
type
|
|
54
|
-
else
|
|
55
|
-
if (field_class = DeclareSchema.to_class(type))
|
|
56
|
-
field_class::COLUMN_TYPE
|
|
57
|
-
end or raise UnknownSqlTypeError, "#{type.inspect} for type #{type.inspect}"
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def deserialize_default_value(column, sql_type, default_value)
|
|
62
|
-
sql_type or raise ArgumentError, "must pass sql_type; got #{sql_type.inspect}"
|
|
51
|
+
def deserialize_default_value(column, type, default_value)
|
|
52
|
+
type or raise ArgumentError, "must pass type; got #{type.inspect}"
|
|
63
53
|
|
|
64
54
|
case Rails::VERSION::MAJOR
|
|
65
55
|
when 4
|
|
66
56
|
# TODO: Delete this Rails 4 support ASAP! This could be wrong, since it's using the type of the old column...which
|
|
67
|
-
# might be getting migrated to a new type. We should be using just
|
|
57
|
+
# might be getting migrated to a new type. We should be using just type as below. -Colin
|
|
68
58
|
column.type_cast_from_database(default_value)
|
|
69
59
|
else
|
|
70
|
-
cast_type = ActiveRecord::Base.connection.send(:lookup_cast_type,
|
|
71
|
-
raise "cast_type not found for #{
|
|
60
|
+
cast_type = ActiveRecord::Base.connection.send(:lookup_cast_type, type) or
|
|
61
|
+
raise "cast_type not found for #{type}"
|
|
72
62
|
cast_type.deserialize(default_value)
|
|
73
63
|
end
|
|
74
64
|
end
|
|
75
65
|
|
|
76
|
-
# Normalizes schema attributes for the
|
|
66
|
+
# Normalizes schema attributes for the given database adapter name.
|
|
77
67
|
# Note that the un-normalized attributes are still useful for generating migrations because those
|
|
78
68
|
# may be run with a different adapter.
|
|
79
|
-
# This method never mutates its argument.
|
|
80
|
-
def normalize_schema_attributes(schema_attributes)
|
|
81
|
-
schema_attributes[:type]
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
schema_attributes
|
|
96
|
-
else
|
|
97
|
-
schema_attributes
|
|
98
|
-
end
|
|
69
|
+
# This method never mutates its argument.
|
|
70
|
+
def normalize_schema_attributes(schema_attributes, db_adapter_name)
|
|
71
|
+
case schema_attributes[:type]
|
|
72
|
+
when :boolean
|
|
73
|
+
schema_attributes.reverse_merge(limit: 1)
|
|
74
|
+
when :integer
|
|
75
|
+
schema_attributes.reverse_merge(limit: 8) if db_adapter_name.match?(/sqlite/i)
|
|
76
|
+
when :float
|
|
77
|
+
schema_attributes.except(:limit)
|
|
78
|
+
when :text
|
|
79
|
+
schema_attributes.except(:limit) if db_adapter_name.match?(/sqlite/i)
|
|
80
|
+
when :datetime
|
|
81
|
+
schema_attributes.reverse_merge(precision: 0)
|
|
82
|
+
when NilClass
|
|
83
|
+
raise ArgumentError, ":type key not found; keys: #{schema_attributes.keys.inspect}"
|
|
84
|
+
end || schema_attributes
|
|
99
85
|
end
|
|
100
86
|
|
|
101
87
|
def equivalent_schema_attributes?(schema_attributes_lhs, schema_attributes_rhs)
|
|
102
|
-
|
|
88
|
+
db_adapter_name = ActiveRecord::Base.connection.class.name
|
|
89
|
+
normalized_lhs = normalize_schema_attributes(schema_attributes_lhs, db_adapter_name)
|
|
90
|
+
normalized_rhs = normalize_schema_attributes(schema_attributes_rhs, db_adapter_name)
|
|
91
|
+
|
|
92
|
+
normalized_lhs == normalized_rhs
|
|
103
93
|
end
|
|
104
94
|
end
|
|
105
95
|
|
|
96
|
+
attr_reader :type
|
|
97
|
+
|
|
106
98
|
def initialize(model, current_table_name, column)
|
|
107
99
|
@model = model or raise ArgumentError, "must pass model"
|
|
108
100
|
@current_table_name = current_table_name or raise ArgumentError, "must pass current_table_name"
|
|
109
101
|
@column = column or raise ArgumentError, "must pass column"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
def sql_type
|
|
113
|
-
@sql_type ||= self.class.sql_type(@column.type)
|
|
102
|
+
@type = @column.type
|
|
103
|
+
self.class.native_type?(@type) or raise UnknownTypeError, "#{@type.inspect}"
|
|
114
104
|
end
|
|
115
105
|
|
|
116
106
|
SCHEMA_KEYS = [:type, :limit, :precision, :scale, :null, :default].freeze
|
|
@@ -121,7 +111,7 @@ module DeclareSchema
|
|
|
121
111
|
value =
|
|
122
112
|
case key
|
|
123
113
|
when :default
|
|
124
|
-
self.class.deserialize_default_value(@column,
|
|
114
|
+
self.class.deserialize_default_value(@column, @type, @column.default)
|
|
125
115
|
else
|
|
126
116
|
col_value = @column.send(key)
|
|
127
117
|
if col_value.nil? && (native_type = self.class.native_types[@column.type])
|
|
@@ -33,7 +33,7 @@ module DeclareSchema
|
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
attr_reader :model, :name, :type, :
|
|
36
|
+
attr_reader :model, :name, :type, :position, :options, :sql_options
|
|
37
37
|
|
|
38
38
|
TYPE_SYNONYMS = { timestamp: :datetime }.freeze # TODO: drop this synonym. -Colin
|
|
39
39
|
|
|
@@ -47,11 +47,9 @@ module DeclareSchema
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def initialize(model, name, type, position: 0, **options)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
|
@@ -62,13 +60,13 @@ module DeclareSchema
|
|
|
62
60
|
|
|
63
61
|
@options.has_key?(:null) or @options[:null] = false
|
|
64
62
|
|
|
65
|
-
case type
|
|
63
|
+
case @type
|
|
66
64
|
when :text
|
|
67
65
|
if self.class.mysql_text_limits?
|
|
68
66
|
@options[:default].nil? or raise MysqlTextMayNotHaveDefault, "when using MySQL, non-nil default may not be given for :text field #{model}##{@name}"
|
|
69
67
|
@options[:limit] = self.class.round_up_mysql_text_limit(@options[:limit] || MYSQL_LONGTEXT_LIMIT)
|
|
70
68
|
else
|
|
71
|
-
@options
|
|
69
|
+
@options.delete(:limit)
|
|
72
70
|
end
|
|
73
71
|
when :string
|
|
74
72
|
@options[:limit] or raise "limit: must be given for :string field #{model}##{@name}: #{@options.inspect}; do you want `limit: 255`?"
|
|
@@ -77,24 +75,23 @@ module DeclareSchema
|
|
|
77
75
|
@options[:limit] = 8
|
|
78
76
|
end
|
|
79
77
|
|
|
80
|
-
|
|
81
|
-
@sql_type = @options.delete(:sql_type) || Column.sql_type(@type)
|
|
78
|
+
Column.native_type?(@type) or raise UnknownTypeError, "#{@type.inspect} not found in #{Column.native_types.inspect} for adapter #{ActiveRecord::Base.connection.class.name}"
|
|
82
79
|
|
|
83
|
-
if @
|
|
84
|
-
@options[:limit] ||= Column.native_types[@
|
|
80
|
+
if @type.in?([:string, :text, :binary, :varbinary, :integer, :enum])
|
|
81
|
+
@options[:limit] ||= Column.native_types[@type][:limit]
|
|
85
82
|
else
|
|
86
|
-
@
|
|
83
|
+
@type != :decimal && @options.has_key?(:limit) and warn("unsupported limit: for SQL type #{@type} in field #{model}##{@name}")
|
|
87
84
|
@options.delete(:limit)
|
|
88
85
|
end
|
|
89
86
|
|
|
90
|
-
if @
|
|
87
|
+
if @type == :decimal
|
|
91
88
|
@options[:precision] or warn("precision: required for :decimal type in field #{model}##{@name}")
|
|
92
89
|
@options[:scale] or warn("scale: required for :decimal type in field #{model}##{@name}")
|
|
93
90
|
else
|
|
94
|
-
if @
|
|
95
|
-
@options.has_key?(:precision) and warn("precision: only allowed for :decimal type or :datetime for SQL type #{@
|
|
91
|
+
if @type != :datetime
|
|
92
|
+
@options.has_key?(:precision) and warn("precision: only allowed for :decimal type or :datetime for SQL type #{@type} in field #{model}##{@name}")
|
|
96
93
|
end
|
|
97
|
-
@options.has_key?(:scale) and warn("scale: only allowed for :decimal type for SQL type #{@
|
|
94
|
+
@options.has_key?(:scale) and warn("scale: only allowed for :decimal type for SQL type #{@type} in field #{model}##{@name}")
|
|
98
95
|
end
|
|
99
96
|
|
|
100
97
|
if @type.in?([:text, :string])
|
|
@@ -106,21 +103,21 @@ module DeclareSchema
|
|
|
106
103
|
@options.delete(:collation)
|
|
107
104
|
end
|
|
108
105
|
else
|
|
109
|
-
@options[:charset] and warn("charset may only given for :string and :text fields for SQL type #{@
|
|
110
|
-
@options[:collation] and warne("collation may only given for :string and :text fields for SQL type #{@
|
|
106
|
+
@options[:charset] and warn("charset may only given for :string and :text fields for SQL type #{@type} in field #{model}##{@name}")
|
|
107
|
+
@options[:collation] and warne("collation may only given for :string and :text fields for SQL type #{@type} in field #{model}##{@name}")
|
|
111
108
|
end
|
|
112
109
|
|
|
113
110
|
@options = Hash[@options.sort_by { |k, _v| OPTION_INDEXES[k] || 9999 }]
|
|
114
111
|
|
|
115
|
-
@sql_options = @options.
|
|
112
|
+
@sql_options = @options.slice(*SQL_OPTIONS)
|
|
116
113
|
end
|
|
117
114
|
|
|
118
115
|
# returns the attributes for schema migrations as a Hash
|
|
119
116
|
# omits name and position since those are meta-data above the schema
|
|
120
117
|
# omits keys with nil values
|
|
121
118
|
def schema_attributes(col_spec)
|
|
122
|
-
@
|
|
123
|
-
attrs[:default] = Column.deserialize_default_value(col_spec, @
|
|
119
|
+
@sql_options.merge(type: @type).tap do |attrs|
|
|
120
|
+
attrs[:default] = Column.deserialize_default_value(col_spec, @type, attrs[:default])
|
|
124
121
|
end.compact
|
|
125
122
|
end
|
|
126
123
|
end
|
|
@@ -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
|
-
|
|
21
|
-
|
|
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) ||
|
|
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
|
|
@@ -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
|
|
|
@@ -328,7 +265,7 @@ module Generators
|
|
|
328
265
|
end
|
|
329
266
|
|
|
330
267
|
def create_table(model)
|
|
331
|
-
longest_field_name = model.field_specs.values.map { |f| f.
|
|
268
|
+
longest_field_name = model.field_specs.values.map { |f| f.type.to_s.length }.max
|
|
332
269
|
disable_auto_increment = model.respond_to?(:disable_auto_increment) && model.disable_auto_increment
|
|
333
270
|
table_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.new(model.table_name, table_options_for_model(model))
|
|
334
271
|
field_definitions = [
|
|
@@ -379,7 +316,7 @@ module Generators
|
|
|
379
316
|
def create_field(field_spec, field_name_width)
|
|
380
317
|
options = field_spec.sql_options.merge(fk_field_options(field_spec.model, field_spec.name))
|
|
381
318
|
args = [field_spec.name.inspect] + format_options(options.compact)
|
|
382
|
-
format("t.%-*s %s", field_name_width, field_spec.
|
|
319
|
+
format("t.%-*s %s", field_name_width, field_spec.type, args.join(', '))
|
|
383
320
|
end
|
|
384
321
|
|
|
385
322
|
def change_table(model, current_table_name)
|
|
@@ -417,7 +354,7 @@ module Generators
|
|
|
417
354
|
args =
|
|
418
355
|
if (spec = model.field_specs[c])
|
|
419
356
|
options = spec.sql_options.merge(fk_field_options(model, c))
|
|
420
|
-
[":#{spec.
|
|
357
|
+
[":#{spec.type}", *format_options(options.compact)]
|
|
421
358
|
else
|
|
422
359
|
[":integer"]
|
|
423
360
|
end
|
|
@@ -444,12 +381,12 @@ module Generators
|
|
|
444
381
|
spec_attrs = spec.schema_attributes(column)
|
|
445
382
|
column_declaration = ::DeclareSchema::Model::Column.new(model, current_table_name, column)
|
|
446
383
|
col_attrs = column_declaration.schema_attributes
|
|
447
|
-
|
|
448
|
-
normalized_schema_attributes = spec_attrs.merge(fk_field_options(model, col_name_to_change))
|
|
384
|
+
normalized_schema_attrs = spec_attrs.merge(fk_field_options(model, col_name_to_change))
|
|
449
385
|
|
|
450
|
-
|
|
386
|
+
if !::DeclareSchema::Model::Column.equivalent_schema_attributes?(normalized_schema_attrs, col_attrs)
|
|
387
|
+
type = normalized_schema_attrs.delete(:type) or raise "no :type found in #{normalized_schema_attrs.inspect}"
|
|
451
388
|
changes << ["change_column #{new_table_name.to_sym.inspect}", col_name_to_change.to_sym.inspect,
|
|
452
|
-
type.to_sym.inspect, *format_options(
|
|
389
|
+
type.to_sym.inspect, *format_options(normalized_schema_attrs)].join(", ")
|
|
453
390
|
undo_changes << change_column_back(model, current_table_name, orig_col_name)
|
|
454
391
|
end
|
|
455
392
|
end
|
|
@@ -6,8 +6,8 @@ rescue LoadError
|
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
RSpec.describe DeclareSchema::Model::FieldSpec do
|
|
9
|
-
let(:model) { double('model', table_options: {}) }
|
|
10
|
-
let(:col_spec) { double('col_spec',
|
|
9
|
+
let(:model) { double('model', table_options: {}, defined_primary_key: 'id') }
|
|
10
|
+
let(:col_spec) { double('col_spec', type: :string) }
|
|
11
11
|
|
|
12
12
|
before do
|
|
13
13
|
load File.expand_path('prepare_testapp.rb', __dir__)
|
|
@@ -22,6 +22,12 @@ RSpec.describe DeclareSchema::Model::FieldSpec do
|
|
|
22
22
|
subject = described_class.new(model, :price, :integer, anonymize_using: 'x', null: false, position: 0, limit: 4)
|
|
23
23
|
expect(subject.options.keys).to eq([:limit, :null, :anonymize_using])
|
|
24
24
|
end
|
|
25
|
+
|
|
26
|
+
it 'raises exception on unknown field type' do
|
|
27
|
+
expect do
|
|
28
|
+
described_class.new(model, :location, :lat_long, position: 0)
|
|
29
|
+
end.to raise_exception(::DeclareSchema::UnknownTypeError, /:lat_long not found in /)
|
|
30
|
+
end
|
|
25
31
|
end
|
|
26
32
|
|
|
27
33
|
describe '#schema_attributes' do
|
|
@@ -127,7 +133,7 @@ RSpec.describe DeclareSchema::Model::FieldSpec do
|
|
|
127
133
|
end
|
|
128
134
|
|
|
129
135
|
describe 'default:' do
|
|
130
|
-
let(:col_spec) { double('col_spec',
|
|
136
|
+
let(:col_spec) { double('col_spec', type: :integer) }
|
|
131
137
|
|
|
132
138
|
it 'typecasts default value' do
|
|
133
139
|
allow(col_spec).to receive(:type_cast_from_database) { |default| Integer(default) }
|
|
@@ -149,8 +155,8 @@ RSpec.describe DeclareSchema::Model::FieldSpec do
|
|
|
149
155
|
end
|
|
150
156
|
end
|
|
151
157
|
|
|
152
|
-
it 'returns the attributes except name, position' do
|
|
153
|
-
subject = described_class.new(model, :price, :bigint, null: true, default: 0, position: 2)
|
|
158
|
+
it 'returns the attributes except name, position, and non-SQL options' do
|
|
159
|
+
subject = described_class.new(model, :price, :bigint, null: true, default: 0, ruby_default: -> { }, encrypt_using: -> { }, position: 2)
|
|
154
160
|
expect(subject.schema_attributes(col_spec)).to eq(type: :integer, limit: 8, null: true, default: 0)
|
|
155
161
|
end
|
|
156
162
|
|
|
@@ -163,4 +169,11 @@ RSpec.describe DeclareSchema::Model::FieldSpec do
|
|
|
163
169
|
expect(bigint.schema_attributes(col_spec)).to eq(expected_attributes)
|
|
164
170
|
end
|
|
165
171
|
end
|
|
172
|
+
|
|
173
|
+
describe '#sql_options' do
|
|
174
|
+
subject { described_class.new(model, :price, :integer, limit: 4, null: true, default: 0, position: 2, encrypt_using: ->(field) { field }) }
|
|
175
|
+
it 'excludes non-sql options' do
|
|
176
|
+
expect(subject.sql_options).to eq(limit: 4, null: true, default: 0)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
166
179
|
end
|
|
@@ -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: \"
|
|
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: \"
|
|
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: \"
|
|
404
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
424
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
446
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
472
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
480
|
-
"remove_foreign_key(\"adverts\", name: \"
|
|
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: \"
|
|
505
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
526
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
547
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
566
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
585
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
604
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
641
|
-
"add_foreign_key(\"adverts\", \"categories\", column: \"c_id\", name: \"
|
|
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: \"
|
|
655
|
-
"remove_foreign_key(\"adverts\", name: \"
|
|
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
|
|
@@ -59,26 +64,6 @@ RSpec.describe DeclareSchema::Model::Column do
|
|
|
59
64
|
end
|
|
60
65
|
end
|
|
61
66
|
|
|
62
|
-
describe '.sql_type' do
|
|
63
|
-
it 'returns the sql type for :string' do
|
|
64
|
-
expect(described_class.sql_type(:string)).to eq(:string)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it 'returns the sql type for :integer' do
|
|
68
|
-
expect(described_class.sql_type(:integer)).to match(:integer)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
it 'returns the sql type for :datetime' do
|
|
72
|
-
expect(described_class.sql_type(:datetime)).to eq(:datetime)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it 'raises UnknownSqlType' do
|
|
76
|
-
expect do
|
|
77
|
-
described_class.sql_type(:email)
|
|
78
|
-
end.to raise_exception(::DeclareSchema::UnknownSqlTypeError, /:email for type :email/)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
67
|
describe '.deserialize_default_value' do
|
|
83
68
|
require 'rails'
|
|
84
69
|
|
|
@@ -109,10 +94,11 @@ RSpec.describe DeclareSchema::Model::Column do
|
|
|
109
94
|
end
|
|
110
95
|
end
|
|
111
96
|
let(:model) { ColumnTestModel }
|
|
97
|
+
let(:type) { :integer }
|
|
112
98
|
let(:current_table_name) { model.table_name }
|
|
113
99
|
let(:column) { double("ActiveRecord Column",
|
|
114
100
|
name: 'count',
|
|
115
|
-
type:
|
|
101
|
+
type: type,
|
|
116
102
|
limit: nil,
|
|
117
103
|
precision: nil,
|
|
118
104
|
scale: nil,
|
|
@@ -122,9 +108,9 @@ RSpec.describe DeclareSchema::Model::Column do
|
|
|
122
108
|
sql_type_metadata: {}) }
|
|
123
109
|
subject { described_class.new(model, current_table_name, column) }
|
|
124
110
|
|
|
125
|
-
describe '#
|
|
126
|
-
it 'returns
|
|
127
|
-
expect(subject.
|
|
111
|
+
describe '#type' do
|
|
112
|
+
it 'returns type' do
|
|
113
|
+
expect(subject.type).to eq(type)
|
|
128
114
|
end
|
|
129
115
|
end
|
|
130
116
|
|
|
@@ -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.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
|
|
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.
|
|
4
|
+
version: 0.8.0.pre.4
|
|
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-
|
|
11
|
+
date: 2021-02-18 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
|