declare_schema 0.8.0.pre.4 → 0.10.0.pre.dc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/declare_schema_build.yml +1 -1
- data/CHANGELOG.md +21 -1
- data/Gemfile.lock +1 -1
- data/README.md +91 -13
- data/lib/declare_schema.rb +46 -0
- data/lib/declare_schema/dsl.rb +40 -0
- data/lib/declare_schema/extensions/active_record/fields_declaration.rb +23 -4
- data/lib/declare_schema/model.rb +51 -59
- data/lib/declare_schema/model/column.rb +2 -0
- data/lib/declare_schema/model/field_spec.rb +12 -9
- data/lib/declare_schema/model/habtm_model_shim.rb +1 -1
- data/lib/declare_schema/version.rb +1 -1
- data/lib/generators/declare_schema/migration/migrator.rb +22 -33
- data/lib/generators/declare_schema/support/model.rb +4 -4
- data/spec/lib/declare_schema/api_spec.rb +7 -7
- data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +41 -15
- data/spec/lib/declare_schema/field_spec_spec.rb +73 -22
- data/spec/lib/declare_schema/generator_spec.rb +3 -3
- data/spec/lib/declare_schema/interactive_primary_key_spec.rb +78 -26
- data/spec/lib/declare_schema/migration_generator_spec.rb +1989 -815
- data/spec/lib/declare_schema/model/column_spec.rb +47 -17
- data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +146 -57
- data/spec/lib/declare_schema/model/habtm_model_shim_spec.rb +3 -3
- data/spec/lib/declare_schema/model/index_definition_spec.rb +188 -77
- data/spec/lib/declare_schema/model/table_options_definition_spec.rb +75 -11
- data/spec/lib/declare_schema_spec.rb +101 -0
- data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +12 -2
- metadata +7 -6
- data/test_responses.txt +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba8cc9ec92cef0b417f1c8a4f19926800f65d81d474bef96daed41073ad01f12
|
4
|
+
data.tar.gz: 78bbc7018dd9b253f1ec294cb00f63df8153e62f26028c2bfbc63934dac0872b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6571074ee8f2961f176d91d3759fd82ac5acf7b8a263f5f2121441003ba7e172148ac50f5946926872b979384ace46cf191382c447f5807a688798813385d73
|
7
|
+
data.tar.gz: 52da509db48d6e858b905c03d553d2af57d1fe67ff540c66e8f9078ac76b4c21441fec99e68befb207151e36c987eda62d3e38b993bb57de5a748ee423456e6a
|
data/CHANGELOG.md
CHANGED
@@ -4,8 +4,26 @@ 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.10.0] - Unreleased
|
8
|
+
### Deprecated
|
9
|
+
- The `fields` dsl method is being deprecated.
|
10
|
+
|
11
|
+
### Added
|
12
|
+
- Added the `declare_schema` method to replace `fields`. We now expect a column's type to come before the name
|
13
|
+
i.e. `declare schema { string :title }`. Otherwise, there is no difference between `fields` and `declare_schema`.
|
14
|
+
|
15
|
+
## [0.9.0] - 2021-03-01
|
16
|
+
### Added
|
17
|
+
- Added configurable default settings for `default_text_limit`, `default_string_limit`, `default_null`,
|
18
|
+
`default_generate_foreign_keys` and `default_generate_indexing` to allow developers to adhere to project conventions.
|
19
|
+
|
20
|
+
### Changed
|
21
|
+
- Moved and deprecated default settings for `default_charset` and `default_collation` from
|
22
|
+
`Generators::DeclareSchema::Migration::Migrator` to `::DeclareSchema`
|
23
|
+
|
24
|
+
## [0.8.0] - 2021-02-22
|
8
25
|
### Removed
|
26
|
+
- Removed assumption that primary key is named 'id'.
|
9
27
|
- Removed `sql_type` that was confusing because it was actually the same as `type` (ex: :string) and not
|
10
28
|
in fact the SQL type (ex: ``varchar(255)'`).
|
11
29
|
|
@@ -130,6 +148,8 @@ using the appropriate Rails configuration attributes.
|
|
130
148
|
### Added
|
131
149
|
- Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
|
132
150
|
|
151
|
+
[0.10.0]: https://github.com/Invoca/declare_schema/compare/v0.9.0...v0.10.0
|
152
|
+
[0.9.0]: https://github.com/Invoca/declare_schema/compare/v0.8.0...v0.9.0
|
133
153
|
[0.8.0]: https://github.com/Invoca/declare_schema/compare/v0.7.1...v0.8.0
|
134
154
|
[0.7.1]: https://github.com/Invoca/declare_schema/compare/v0.7.0...v0.7.1
|
135
155
|
[0.7.0]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.7.0
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -70,18 +70,85 @@ DeclareSchema::Migration::Migrator.before_generating_migration do
|
|
70
70
|
end
|
71
71
|
```
|
72
72
|
|
73
|
-
|
74
|
-
|
73
|
+
### Global Configuration
|
74
|
+
Configurations can be set at the global level to customize default declaration for the following values:
|
75
75
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
tables and columns in the database. With `declare_schema` this can be configured
|
82
|
-
at three separate levels
|
76
|
+
#### Text Limit
|
77
|
+
The default text limit can be set using the `DeclareSchema.default_text_limit=` method.
|
78
|
+
Note that a `nil` default means that there is no default-- so every declaration must be explicit.
|
79
|
+
This will `raise` a `limit: must be provided for field :text...` error when the default value is `nil` and there is no explicit
|
80
|
+
declaration.
|
83
81
|
|
84
|
-
|
82
|
+
For example, adding the following to your `config/initializers` directory will
|
83
|
+
set the default `text limit` value to `0xffff`:
|
84
|
+
|
85
|
+
**declare_schema.rb**
|
86
|
+
```ruby
|
87
|
+
# frozen_string_literal: true
|
88
|
+
|
89
|
+
DeclareSchema.default_text_limit = 0xffff
|
90
|
+
```
|
91
|
+
|
92
|
+
#### String Limit
|
93
|
+
The default string limit can be set using the `DeclareSchema.default_string_limit=` method.
|
94
|
+
Note that a `nil` default means that there is no default-- so every declaration must be explicit.
|
95
|
+
This will `raise` a `limit: must be provided for field :string...` error when the default value is `nil` and there is no explicit
|
96
|
+
declaration.
|
97
|
+
|
98
|
+
For example, adding the following to your `config/initializers` directory will
|
99
|
+
set the default `string limit` value to `255`:
|
100
|
+
|
101
|
+
**declare_schema.rb**
|
102
|
+
```ruby
|
103
|
+
# frozen_string_literal: true
|
104
|
+
|
105
|
+
DeclareSchema.default_string_limit = 255
|
106
|
+
```
|
107
|
+
|
108
|
+
#### Null
|
109
|
+
The default null value can be set using the `DeclareSchema.default_null=` method.
|
110
|
+
Note that a `nil` default means that there is no default-- so every declaration must be explicit.
|
111
|
+
This will `raise` a `null: must be provided for field...` error when the default value is `nil` and there is no explicit
|
112
|
+
declaration.
|
113
|
+
|
114
|
+
For example, adding the following to your `config/initializers` directory will
|
115
|
+
set the default `null` value to `true`:
|
116
|
+
|
117
|
+
**declare_schema.rb**
|
118
|
+
```ruby
|
119
|
+
# frozen_string_literal: true
|
120
|
+
|
121
|
+
DeclareSchema.default_null = true
|
122
|
+
```
|
123
|
+
|
124
|
+
#### Generate Foreign Keys
|
125
|
+
The default value for generate foreign keys can be set using the `DeclareSchema.default_generate_foreign_keys=` method.
|
126
|
+
This value defaults to `true` and can only be set at the global level.
|
127
|
+
|
128
|
+
For example, adding the following to your `config/initializers` directory will set
|
129
|
+
the default `generate foreign keys` value to `false`:
|
130
|
+
|
131
|
+
**declare_schema.rb**
|
132
|
+
```ruby
|
133
|
+
# frozen_string_literal: true
|
134
|
+
|
135
|
+
DeclareSchema.default_generate_foreign_keys = false
|
136
|
+
```
|
137
|
+
|
138
|
+
#### Generate Indexing
|
139
|
+
The default value for generate indexing can be set using the `DeclareSchema.default_generate_indexing=` method.
|
140
|
+
This value defaults to `true` and can only be set at the global level.
|
141
|
+
|
142
|
+
For example, adding the following to your `config/initializers` directory will
|
143
|
+
set the default `generate indexing` value to `false`:
|
144
|
+
|
145
|
+
**declare_schema.rb**
|
146
|
+
```ruby
|
147
|
+
# frozen_string_literal: true
|
148
|
+
|
149
|
+
DeclareSchema.default_generate_indexing = false
|
150
|
+
```
|
151
|
+
#### Character Set and Collation
|
85
152
|
The character set and collation for all tables and fields can be set at the global level
|
86
153
|
using the `Generators::DeclareSchema::Migrator.default_charset=` and
|
87
154
|
`Generators::DeclareSchema::Migrator.default_collation=` configuration methods.
|
@@ -93,10 +160,21 @@ turn all tables into `utf8mb4` supporting tables:
|
|
93
160
|
```ruby
|
94
161
|
# frozen_string_literal: true
|
95
162
|
|
96
|
-
|
97
|
-
|
163
|
+
DeclareSchema.default_charset = "utf8mb4"
|
164
|
+
DeclareSchema.default_collation = "utf8mb4_bin"
|
98
165
|
```
|
99
166
|
|
167
|
+
## Declaring Character Set and Collation
|
168
|
+
_Note: This feature currently only works for MySQL database configurations._
|
169
|
+
|
170
|
+
MySQL originally supported UTF-8 in the range of 1-3 bytes (`mb3` or "multi-byte 3")
|
171
|
+
which covered the full set of Unicode code points at the time: U+0000 - U+FFFF.
|
172
|
+
But later, Unicode was extended beyond U+FFFF to make room for emojis, and with that
|
173
|
+
UTF-8 require 1-4 bytes (`mb4` or "multi-byte 4"). With this addition, there has
|
174
|
+
come a need to dynamically define the character set and collation for individual
|
175
|
+
tables and columns in the database. With `declare_schema` this can be configured
|
176
|
+
at three separate levels
|
177
|
+
|
100
178
|
### Table Configuration
|
101
179
|
In order to configure a table's default character set and collation, the `charset` and
|
102
180
|
`collation` arguments can be added to the `fields` block.
|
@@ -150,5 +228,5 @@ or add it to your `bundler` Gemfile:
|
|
150
228
|
To run tests:
|
151
229
|
```
|
152
230
|
rake test:prepare_testapp[force]
|
153
|
-
rake test:all
|
231
|
+
rake test:all
|
154
232
|
```
|
data/lib/declare_schema.rb
CHANGED
@@ -21,7 +21,18 @@ module DeclareSchema
|
|
21
21
|
text: String
|
22
22
|
}.freeze
|
23
23
|
|
24
|
+
@default_charset = "utf8mb4"
|
25
|
+
@default_collation = "utf8mb4_bin"
|
26
|
+
@default_text_limit = 0xffff_ffff
|
27
|
+
@default_string_limit = nil
|
28
|
+
@default_null = false
|
29
|
+
@default_generate_foreign_keys = true
|
30
|
+
@default_generate_indexing = true
|
31
|
+
|
24
32
|
class << self
|
33
|
+
attr_reader :default_charset, :default_collation, :default_text_limit, :default_string_limit, :default_null,
|
34
|
+
:default_generate_foreign_keys, :default_generate_indexing
|
35
|
+
|
25
36
|
def to_class(type)
|
26
37
|
case type
|
27
38
|
when Class
|
@@ -32,6 +43,41 @@ module DeclareSchema
|
|
32
43
|
raise ArgumentError, "expected Class or Symbol or String: got #{type.inspect}"
|
33
44
|
end
|
34
45
|
end
|
46
|
+
|
47
|
+
def default_charset=(charset)
|
48
|
+
charset.is_a?(String) or raise ArgumentError, "charset must be a string (got #{charset.inspect})"
|
49
|
+
@default_charset = charset
|
50
|
+
end
|
51
|
+
|
52
|
+
def default_collation=(collation)
|
53
|
+
collation.is_a?(String) or raise ArgumentError, "collation must be a string (got #{collation.inspect})"
|
54
|
+
@default_collation = collation
|
55
|
+
end
|
56
|
+
|
57
|
+
def default_text_limit=(text_limit)
|
58
|
+
text_limit.nil? or text_limit.is_a?(Integer) or raise ArgumentError, "text limit must be an integer or nil (got #{text_limit.inspect})"
|
59
|
+
@default_text_limit = text_limit
|
60
|
+
end
|
61
|
+
|
62
|
+
def default_string_limit=(string_limit)
|
63
|
+
string_limit.nil? or string_limit.is_a?(Integer) or raise ArgumentError, "string limit must be an integer or nil (got #{string_limit.inspect})"
|
64
|
+
@default_string_limit = string_limit
|
65
|
+
end
|
66
|
+
|
67
|
+
def default_null=(null)
|
68
|
+
null.in?([true, false, nil]) or raise ArgumentError, "null must be either true, false, or nil (got #{null.inspect})"
|
69
|
+
@default_null = null
|
70
|
+
end
|
71
|
+
|
72
|
+
def default_generate_foreign_keys=(generate_foreign_keys)
|
73
|
+
generate_foreign_keys.in?([true, false]) or raise ArgumentError, "generate_foreign_keys must be either true or false (got #{generate_foreign_keys.inspect})"
|
74
|
+
@default_generate_foreign_keys = generate_foreign_keys
|
75
|
+
end
|
76
|
+
|
77
|
+
def default_generate_indexing=(generate_indexing)
|
78
|
+
generate_indexing.in?([true, false]) or raise ArgumentError, "generate_indexing must be either true or false (got #{generate_indexing.inspect})"
|
79
|
+
@default_generate_indexing = generate_indexing
|
80
|
+
end
|
35
81
|
end
|
36
82
|
end
|
37
83
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/proxy_object'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
class Dsl < BasicObject # avoid Object because that gets extended by lots of gems
|
7
|
+
include ::Kernel # but we need the basic class methods
|
8
|
+
|
9
|
+
instance_methods.each do |m|
|
10
|
+
unless m.to_s.starts_with?('__') || m.in?([:object_id, :instance_eval])
|
11
|
+
undef_method(m)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(model, options = {})
|
16
|
+
@model = model
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :model
|
21
|
+
|
22
|
+
def timestamps
|
23
|
+
field(:created_at, :datetime, null: true)
|
24
|
+
field(:updated_at, :datetime, null: true)
|
25
|
+
end
|
26
|
+
|
27
|
+
def optimistic_lock
|
28
|
+
field(:lock_version, :integer, default: 1, null: false)
|
29
|
+
end
|
30
|
+
|
31
|
+
def field(name, type, *args)
|
32
|
+
options = args.extract_options!
|
33
|
+
@model.declare_field(name, type, *(args + [@options.merge(options)]))
|
34
|
+
end
|
35
|
+
|
36
|
+
def method_missing(type, name, *args)
|
37
|
+
field(name, type, *args)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,21 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_record'
|
4
|
+
require 'declare_schema/dsl'
|
4
5
|
require 'declare_schema/model'
|
5
6
|
require 'declare_schema/field_declaration_dsl'
|
6
7
|
|
7
8
|
module DeclareSchema
|
8
|
-
module
|
9
|
+
module Macros
|
9
10
|
def fields(table_options = {}, &block)
|
10
11
|
# Any model that calls 'fields' gets DeclareSchema::Model behavior
|
11
12
|
DeclareSchema::Model.mix_in(self)
|
12
13
|
|
13
|
-
# @include_in_migration = false #||= options.fetch(:include_in_migration, true); options.delete(:include_in_migration)
|
14
14
|
@include_in_migration = true
|
15
15
|
@table_options = table_options
|
16
16
|
|
17
17
|
if block
|
18
|
-
dsl = DeclareSchema::FieldDeclarationDsl.new(self
|
18
|
+
dsl = DeclareSchema::FieldDeclarationDsl.new(self)
|
19
|
+
if block.arity == 1
|
20
|
+
yield dsl
|
21
|
+
else
|
22
|
+
dsl.instance_eval(&block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
deprecate :fields, deprecator: ActiveSupport::Deprecation.new('1.0', 'DeclareSchema')
|
27
|
+
|
28
|
+
def declare_schema(table_options = {}, &block)
|
29
|
+
# Any model that calls 'fields' gets DeclareSchema::Model behavior
|
30
|
+
DeclareSchema::Model.mix_in(self)
|
31
|
+
|
32
|
+
# @include_in_migration = false #||= options.fetch(:include_in_migration, true); options.delete(:include_in_migration)
|
33
|
+
@include_in_migration = true # TODO: Add back or delete the include_in_migration feature
|
34
|
+
@table_options = table_options
|
35
|
+
|
36
|
+
if block
|
37
|
+
dsl = DeclareSchema::Dsl.new(self, null: false)
|
19
38
|
if block.arity == 1
|
20
39
|
yield dsl
|
21
40
|
else
|
@@ -26,4 +45,4 @@ module DeclareSchema
|
|
26
45
|
end
|
27
46
|
end
|
28
47
|
|
29
|
-
ActiveRecord::Base.singleton_class.prepend DeclareSchema::
|
48
|
+
ActiveRecord::Base.singleton_class.prepend DeclareSchema::Macros
|
data/lib/declare_schema/model.rb
CHANGED
@@ -38,24 +38,24 @@ module DeclareSchema
|
|
38
38
|
|
39
39
|
# eval avoids the ruby 1.9.2 "super from singleton method ..." error
|
40
40
|
|
41
|
-
eval
|
41
|
+
eval <<~EOS
|
42
42
|
def self.inherited(klass)
|
43
43
|
unless klass.field_specs.has_key?(inheritance_column)
|
44
|
-
|
44
|
+
declare_schema do |f|
|
45
45
|
f.field(inheritance_column, :string, limit: 255, null: true)
|
46
46
|
end
|
47
47
|
index(inheritance_column)
|
48
48
|
end
|
49
49
|
super
|
50
50
|
end
|
51
|
-
|
51
|
+
EOS
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
module ClassMethods
|
57
57
|
def index(fields, options = {})
|
58
|
-
#
|
58
|
+
# make index idempotent
|
59
59
|
index_fields_s = Array.wrap(fields).map(&:to_s)
|
60
60
|
unless index_definitions.any? { |index_spec| index_spec.fields == index_fields_s }
|
61
61
|
index_definitions << ::DeclareSchema::Model::IndexDefinition.new(self, fields, options)
|
@@ -74,7 +74,7 @@ module DeclareSchema
|
|
74
74
|
end
|
75
75
|
|
76
76
|
# tell the migration generator to ignore the named index. Useful for existing indexes, or for indexes
|
77
|
-
# that can't be automatically generated (for example:
|
77
|
+
# that can't be automatically generated (for example: a prefix index in MySQL)
|
78
78
|
def ignore_index(index_name)
|
79
79
|
ignore_indexes << index_name.to_s
|
80
80
|
end
|
@@ -85,10 +85,10 @@ module DeclareSchema
|
|
85
85
|
# declarations.
|
86
86
|
def declare_field(name, type, *args, **options)
|
87
87
|
try(:field_added, name, type, args, options)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
88
|
+
_add_serialize_for_field(name, type, options)
|
89
|
+
_add_formatting_for_field(name, type)
|
90
|
+
_add_validations_for_field(name, type, args, options)
|
91
|
+
_add_index_for_field(name, args, options)
|
92
92
|
field_specs[name] = ::DeclareSchema::Model::FieldSpec.new(self, name, type, position: field_specs.size, **options)
|
93
93
|
attr_order << name unless attr_order.include?(name)
|
94
94
|
end
|
@@ -97,41 +97,10 @@ module DeclareSchema
|
|
97
97
|
if index_definitions.any?(&:primary_key?)
|
98
98
|
index_definitions
|
99
99
|
else
|
100
|
-
index_definitions + [
|
100
|
+
index_definitions + [_rails_default_primary_key]
|
101
101
|
end
|
102
102
|
end
|
103
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
|
127
|
-
end
|
128
|
-
|
129
|
-
private
|
130
|
-
|
131
|
-
def rails_default_primary_key
|
132
|
-
::DeclareSchema::Model::IndexDefinition.new(self, [primary_key.to_sym], unique: true, name: DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME)
|
133
|
-
end
|
134
|
-
|
135
104
|
# Extend belongs_to so that it creates a FieldSpec for the foreign key
|
136
105
|
def belongs_to(name, scope = nil, **options)
|
137
106
|
column_options = {}
|
@@ -172,7 +141,7 @@ module DeclareSchema
|
|
172
141
|
declare_field(fkey.to_sym, :integer, column_options)
|
173
142
|
if refl.options[:polymorphic]
|
174
143
|
foreign_type = options[:foreign_type] || "#{name}_type"
|
175
|
-
|
144
|
+
_declare_polymorphic_type_field(foreign_type, column_options)
|
176
145
|
index([foreign_type, fkey], index_options) if index_options[:name] != false
|
177
146
|
else
|
178
147
|
index(fkey, index_options) if index_options[:name] != false
|
@@ -180,26 +149,49 @@ module DeclareSchema
|
|
180
149
|
end
|
181
150
|
end
|
182
151
|
|
152
|
+
if ::Rails::VERSION::MAJOR < 5
|
153
|
+
def primary_key
|
154
|
+
super || 'id'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# returns the primary key (String) as declared with primary_key =
|
159
|
+
# unlike the `primary_key` method, DOES NOT query the database to find the actual primary key in use right now
|
160
|
+
# if no explicit primary key set, returns the default_defined_primary_key
|
161
|
+
def _defined_primary_key
|
162
|
+
if defined?(@primary_key)
|
163
|
+
@primary_key&.to_s
|
164
|
+
end || _default_defined_primary_key
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
# if this is a derived class, returns the base class's _defined_primary_key
|
170
|
+
# otherwise, returns 'id'
|
171
|
+
def _default_defined_primary_key
|
172
|
+
if self == base_class
|
173
|
+
'id'
|
174
|
+
else
|
175
|
+
base_class._defined_primary_key
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def _rails_default_primary_key
|
180
|
+
::DeclareSchema::Model::IndexDefinition.new(self, [_defined_primary_key.to_sym], unique: true, name: DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME)
|
181
|
+
end
|
182
|
+
|
183
183
|
# Declares the "foo_type" field that accompanies the "foo_id"
|
184
184
|
# field for a polymorphic belongs_to
|
185
|
-
def
|
185
|
+
def _declare_polymorphic_type_field(foreign_type, column_options)
|
186
186
|
declare_field(foreign_type, :string, column_options.merge(limit: 255))
|
187
187
|
# FIXME: Before declare_schema was extracted, this used to now do:
|
188
188
|
# never_show(type_col)
|
189
189
|
# That needs doing somewhere
|
190
190
|
end
|
191
191
|
|
192
|
-
# Declare a rich-type for any attribute (i.e. getter method). This
|
193
|
-
# does not effect the attribute in any way - it just records the
|
194
|
-
# metadata.
|
195
|
-
def declare_attr_type(name, type, options = {})
|
196
|
-
attr_types[name] = klass = DeclareSchema.to_class(type)
|
197
|
-
klass.try(:declared, self, name, options)
|
198
|
-
end
|
199
|
-
|
200
192
|
# Add field validations according to arguments in the
|
201
193
|
# field declaration
|
202
|
-
def
|
194
|
+
def _add_validations_for_field(name, type, args, options)
|
203
195
|
validates_presence_of name if :required.in?(args)
|
204
196
|
validates_uniqueness_of name, allow_nil: !:required.in?(args) if :unique.in?(args)
|
205
197
|
|
@@ -218,18 +210,18 @@ module DeclareSchema
|
|
218
210
|
end
|
219
211
|
end
|
220
212
|
|
221
|
-
def
|
213
|
+
def _add_serialize_for_field(name, type, options)
|
222
214
|
if (serialize_class = options.delete(:serialize))
|
223
215
|
type == :string || type == :text or raise ArgumentError, "serialize field type must be :string or :text"
|
224
216
|
serialize_args = Array((serialize_class unless serialize_class == true))
|
225
217
|
serialize(name, *serialize_args)
|
226
218
|
if options.has_key?(:default)
|
227
|
-
options[:default] =
|
219
|
+
options[:default] = _serialized_default(name, serialize_class == true ? Object : serialize_class, options[:default])
|
228
220
|
end
|
229
221
|
end
|
230
222
|
end
|
231
223
|
|
232
|
-
def
|
224
|
+
def _serialized_default(attr_name, class_name_or_coder, default)
|
233
225
|
# copied from https://github.com/rails/rails/blob/7d6cb950e7c0e31c2faaed08c81743439156c9f5/activerecord/lib/active_record/attribute_methods/serialization.rb#L70-L76
|
234
226
|
coder = if class_name_or_coder == ::JSON
|
235
227
|
ActiveRecord::Coders::JSON
|
@@ -248,7 +240,7 @@ module DeclareSchema
|
|
248
240
|
end
|
249
241
|
end
|
250
242
|
|
251
|
-
def
|
243
|
+
def _add_formatting_for_field(name, type)
|
252
244
|
if (type_class = DeclareSchema.to_class(type))
|
253
245
|
if "format".in?(type_class.instance_methods)
|
254
246
|
before_validation do |record|
|
@@ -258,7 +250,7 @@ module DeclareSchema
|
|
258
250
|
end
|
259
251
|
end
|
260
252
|
|
261
|
-
def
|
253
|
+
def _add_index_for_field(name, args, options)
|
262
254
|
if (to_name = options.delete(:index))
|
263
255
|
index_opts =
|
264
256
|
{
|
@@ -287,13 +279,13 @@ module DeclareSchema
|
|
287
279
|
refl
|
288
280
|
end
|
289
281
|
end ||
|
290
|
-
if (col =
|
282
|
+
if (col = _column(name.to_s))
|
291
283
|
DeclareSchema::PLAIN_TYPES[col.type] || col.klass
|
292
284
|
end
|
293
285
|
end
|
294
286
|
|
295
287
|
# Return the entry from #columns for the named column
|
296
|
-
def
|
288
|
+
def _column(name)
|
297
289
|
defined?(@table_exists) or @table_exists = table_exists?
|
298
290
|
if @table_exists
|
299
291
|
columns_hash[name.to_s]
|