declare_schema 0.7.1 → 0.8.0.pre.5
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 +6 -0
- data/Gemfile.lock +1 -1
- data/lib/declare_schema/model.rb +25 -2
- data/lib/declare_schema/model/column.rb +11 -20
- data/lib/declare_schema/model/field_spec.rb +17 -20
- 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 +4 -67
- data/spec/lib/declare_schema/field_spec_spec.rb +9 -3
- 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: c8a020c30e79336f89851e73eaabbb8dcdfd2affed27883e7d4fe06944f76436
|
4
|
+
data.tar.gz: e17f1fe94f3dc8188469df87679ee09c955765f2a5ac45354928e6664c026bae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccf0846c28e2e0a7d20db08d3ad925fc22d7ed1d5a3cb2f75df3585ce4b42a00663f2550b17ce648d9a86e7e58a7d0a367f43ef21138f6fc838ea8f4b39ec8db
|
7
|
+
data.tar.gz: a5fa4637da88f364ec303ebe0d615e6e0e99caef81e7965d753cf04d8cb33b787efef874ef5b71db3e6a0f1f850087b617a7f6f811cc9fc8d307f7d01562da25
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,11 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
4
4
|
|
5
5
|
Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [0.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
|
+
|
7
12
|
## [0.7.1] - 2021-02-17
|
8
13
|
### Fixed
|
9
14
|
- Exclude unknown options from FieldSpec#sql_options and #schema_attributes.
|
@@ -125,6 +130,7 @@ using the appropriate Rails configuration attributes.
|
|
125
130
|
### Added
|
126
131
|
- Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
|
127
132
|
|
133
|
+
[0.8.0]: https://github.com/Invoca/declare_schema/compare/v0.7.1...v0.8.0
|
128
134
|
[0.7.1]: https://github.com/Invoca/declare_schema/compare/v0.7.0...v0.7.1
|
129
135
|
[0.7.0]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.7.0
|
130
136
|
[0.6.4]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.6.4
|
data/Gemfile.lock
CHANGED
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
|
@@ -99,8 +101,29 @@ module DeclareSchema
|
|
99
101
|
end
|
100
102
|
end
|
101
103
|
|
102
|
-
|
103
|
-
|
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
|
104
127
|
end
|
105
128
|
|
106
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,27 +48,17 @@ 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
|
@@ -103,13 +93,14 @@ module DeclareSchema
|
|
103
93
|
end
|
104
94
|
end
|
105
95
|
|
106
|
-
attr_reader :
|
96
|
+
attr_reader :type
|
107
97
|
|
108
98
|
def initialize(model, current_table_name, column)
|
109
99
|
@model = model or raise ArgumentError, "must pass model"
|
110
100
|
@current_table_name = current_table_name or raise ArgumentError, "must pass current_table_name"
|
111
101
|
@column = column or raise ArgumentError, "must pass column"
|
112
|
-
@
|
102
|
+
@type = @column.type
|
103
|
+
self.class.native_type?(@type) or raise UnknownTypeError, "#{@type.inspect}"
|
113
104
|
end
|
114
105
|
|
115
106
|
SCHEMA_KEYS = [:type, :limit, :precision, :scale, :null, :default].freeze
|
@@ -120,7 +111,7 @@ module DeclareSchema
|
|
120
111
|
value =
|
121
112
|
case key
|
122
113
|
when :default
|
123
|
-
self.class.deserialize_default_value(@column, @
|
114
|
+
self.class.deserialize_default_value(@column, @type, @column.default)
|
124
115
|
else
|
125
116
|
col_value = @column.send(key)
|
126
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.dig(@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,8 +103,8 @@ 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 }]
|
@@ -120,7 +117,7 @@ module DeclareSchema
|
|
120
117
|
# omits keys with nil values
|
121
118
|
def schema_attributes(col_spec)
|
122
119
|
@sql_options.merge(type: @type).tap do |attrs|
|
123
|
-
attrs[:default] = Column.deserialize_default_value(col_spec, @
|
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
|
@@ -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) }
|
@@ -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.5
|
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-19 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
|