schemattr 0.0.1 → 0.2.0
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 +0 -0
- data/{MIT.LICENSE → MIT-LICENSE} +1 -3
- data/README.md +63 -72
- data/lib/schemattr/active_record_extension.rb +7 -6
- data/lib/schemattr/attribute.rb +28 -27
- data/lib/schemattr/dsl.rb +64 -53
- data/lib/schemattr/version.rb +15 -1
- data/lib/schemattr.rb +3 -1
- metadata +37 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ed48f215b1651cfcaca945564ee28889209196633128c453c25050c93948092
|
4
|
+
data.tar.gz: 1d93e1999e211d8168b2f1dea9bb650043afe606a0c6c2eeb006689a6f4184eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e38303d1c00e993a70b4f64dd37287aef23b3eac18a4a233482adc01e9ed90714a71b50128208eb8f46ec26d2e0c5e7c965470cf9e4cbd7b328a663ca0492f6e
|
7
|
+
data.tar.gz: 43361ee53cabc37ca4f3e538cf93d1fb4328584e4564e0230cb7a352a375d59895c7ca9503fa71e3287638490780bc7cd0b80de1fd56a40ffbfc0f2a311fd302
|
data/CHANGELOG.md
ADDED
File without changes
|
data/{MIT.LICENSE → MIT-LICENSE}
RENAMED
data/README.md
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
Schemattr
|
2
|
-
=========
|
1
|
+
# Schemattr - Schema-ish ActiveRecord attributes
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
[](https://rubygems.org/gems/schemattr)
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
7
|
+
[](https://github.com/jejacks0n/schemattr/actions/workflows/ci.yml)
|
8
|
+
[](https://codeclimate.com/github/jejacks0n/schemattr/maintainability)
|
9
|
+
[](https://codeclimate.com/github/jejacks0n/schemattr/test_coverage)
|
10
|
+
[](https://rubygems.org/gems/schemattr)
|
10
11
|
|
11
12
|
Schemattr is an ActiveRecord extension that provides a helpful schema-less attribute DSL. It can be used to define a
|
12
13
|
simple schema for a single attribute that can change over time without having to migrate existing data.
|
@@ -34,36 +35,23 @@ methods, can keep a real column synced with one if its fields, and more.
|
|
34
35
|
If you're using Schemattr and want to add a new setting field, it's as simple as adding a new field to the attribute
|
35
36
|
schema and setting a default right there in the code. No migrations, no hassles, easy deployment.
|
36
37
|
|
38
|
+
## Download and Installation
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
1. [Installation](#installation)
|
41
|
-
2. [Usage](#usage)
|
42
|
-
- [Field types](#field-types)
|
43
|
-
- [Delegating](#delegating)
|
44
|
-
- [Strict mode](#strict-mode-vs-arbitrary-fields)
|
45
|
-
- [Overriding](#overriding-functionality)
|
46
|
-
- [Renaming fields](#renaming-fields)
|
47
|
-
- [Syncing attributes](#syncing-attributes)
|
48
|
-
|
40
|
+
Add this line to your Gemfile:
|
49
41
|
|
50
|
-
## Installation
|
51
|
-
|
52
|
-
Add it to your Gemfile:
|
53
42
|
```ruby
|
54
|
-
gem
|
43
|
+
gem "schemattr"
|
55
44
|
```
|
56
45
|
|
57
|
-
|
58
|
-
```shell
|
59
|
-
$ bundle
|
60
|
-
```
|
46
|
+
Or install the latest version with RubyGems:
|
61
47
|
|
62
|
-
|
63
|
-
|
64
|
-
$ gem install schemattr
|
48
|
+
```bash
|
49
|
+
gem install schemattr
|
65
50
|
```
|
66
51
|
|
52
|
+
Source code can be downloaded as part of the project on GitHub:
|
53
|
+
|
54
|
+
* https://github.com/jejacks0n/schemattr
|
67
55
|
|
68
56
|
## Usage
|
69
57
|
|
@@ -73,7 +61,7 @@ First, let's create a migration to add your schema-less attribute. In postgres y
|
|
73
61
|
postgres JSON type as our example because the JSON type allows queries and indexing, and hstore does annoying things to
|
74
62
|
booleans. We don't need to set our default value to an empty object because Schemattr handles that for us.
|
75
63
|
|
76
|
-
|
64
|
+
_Note_: If you're using a different database provider, like sqlite3 for instance, you can use a text column and tell
|
77
65
|
ActiveRecord to serialize that column (e.g. `serialize :settings` in your model). Though, you won't be able to easily
|
78
66
|
query in these cases so consider your options.
|
79
67
|
|
@@ -104,8 +92,8 @@ Notice that we've done nothing else, but we already have a working version of wh
|
|
104
92
|
```
|
105
93
|
user = User.new
|
106
94
|
user.settings.opted_in? # => true
|
107
|
-
user.settings.email_group_advanced? # => false
|
108
|
-
user.settings.email_group_expert? # => false
|
95
|
+
user.settings.email_group_advanced? # => false
|
96
|
+
user.settings.email_group_expert? # => false
|
109
97
|
```
|
110
98
|
|
111
99
|
If we save the user at this point, these settings will be persisted. We can also make changes to them at this point, and
|
@@ -117,18 +105,19 @@ they'll just be the defaults if we ever ask again.
|
|
117
105
|
The various field types are outlined below. When you define a string field for instance, the value will be coerced into
|
118
106
|
a string at the time that it's set.
|
119
107
|
|
120
|
-
type | description
|
121
|
-
|
122
|
-
boolean | boolean value
|
123
|
-
string | string value
|
124
|
-
text | same as string type
|
125
|
-
integer | number value
|
126
|
-
bigint | same as integer
|
127
|
-
float | floating point number value
|
128
|
-
decimal | same as float
|
129
|
-
datetime | datetime object
|
130
|
-
time | time object (stored the same as datetime)
|
131
|
-
date | date object
|
108
|
+
| type | description |
|
109
|
+
|----------|-------------------------------------------|
|
110
|
+
| boolean | boolean value |
|
111
|
+
| string | string value |
|
112
|
+
| text | same as string type |
|
113
|
+
| integer | number value |
|
114
|
+
| bigint | same as integer |
|
115
|
+
| float | floating point number value |
|
116
|
+
| decimal | same as float |
|
117
|
+
| datetime | datetime object |
|
118
|
+
| time | time object (stored the same as datetime) |
|
119
|
+
| date | date object |
|
120
|
+
| hash | hash object |
|
132
121
|
|
133
122
|
You can additionally define your own types using `field :foo, :custom_type` and there will no coercion at the time the
|
134
123
|
field is set -- this is intended for when you need something that doesn't care what type it is. This generally makes it
|
@@ -140,9 +129,9 @@ If you don't like the idea of having to access these attributes at `user.setting
|
|
140
129
|
delegated. This adds delegation of the methods that exist on settings to the User instances.
|
141
130
|
|
142
131
|
```ruby
|
143
|
-
|
144
|
-
|
145
|
-
|
132
|
+
attribute_schema :settings, delegated: true do
|
133
|
+
field :opted_in, :boolean, default: true
|
134
|
+
end
|
146
135
|
```
|
147
136
|
|
148
137
|
```ruby
|
@@ -157,13 +146,13 @@ user.opted_in? # => false
|
|
157
146
|
By default, Schemattr doesn't allow arbitrary fields to be added, but it supports it. When strict mode is disabled, it
|
158
147
|
allows any arbitrary field to be set or asked for.
|
159
148
|
|
160
|
-
|
149
|
+
_Note_: When delegated and strict mode is disabled, you cannot set arbitrary fields on the model directly and must
|
161
150
|
access them through the attribute that you've defined -- in our case, it's `settings`.
|
162
151
|
|
163
152
|
```ruby
|
164
|
-
|
165
|
-
|
166
|
-
|
153
|
+
attribute_schema :settings, delegated: true, strict: false do
|
154
|
+
field :opted_in, :boolean, default: true
|
155
|
+
end
|
167
156
|
```
|
168
157
|
|
169
158
|
```ruby
|
@@ -186,17 +175,17 @@ class UserSettings < Schemattr::Attribute
|
|
186
175
|
!self[:opted_in]
|
187
176
|
end
|
188
177
|
alias_method :opted_out, :opted_out?
|
189
|
-
|
178
|
+
|
190
179
|
def opted_out=(val)
|
191
|
-
opted_in = !val
|
180
|
+
self.opted_in = !val
|
192
181
|
end
|
193
182
|
end
|
194
183
|
```
|
195
184
|
|
196
185
|
```ruby
|
197
|
-
|
198
|
-
|
199
|
-
|
186
|
+
attribute_schema :settings, class: UserSettings do
|
187
|
+
field :opted_in, :boolean, default: true
|
188
|
+
end
|
200
189
|
```
|
201
190
|
|
202
191
|
```ruby
|
@@ -230,7 +219,7 @@ class UserSettings < Schemattr::Attribute
|
|
230
219
|
end
|
231
220
|
```
|
232
221
|
|
233
|
-
|
222
|
+
_Note_: This is not a real world scenario but serves our purposes of describing an example.
|
234
223
|
|
235
224
|
### Renaming fields
|
236
225
|
|
@@ -240,16 +229,18 @@ shown thus far. But you've added new email lists, and you think `opted_in` is to
|
|
240
229
|
We can create a new field that is correctly named, and specify what attribute we want to pull the value from.
|
241
230
|
|
242
231
|
```ruby
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
232
|
+
attribute_schema :settings do
|
233
|
+
# field :opted_in, :boolean, default: true
|
234
|
+
field :email_list_beginner, :boolean, value_from: :opted_in, default: true
|
235
|
+
end
|
247
236
|
```
|
248
237
|
|
249
|
-
Specifying the `
|
238
|
+
Specifying the `value_from: :opted_in` option will tell Schemattr to look for the value that may have already been defined in
|
250
239
|
`opted_in` before the rename. This allows for slow migrations, but you can also write a migration to ensure this happens
|
251
240
|
quickly.
|
252
241
|
|
242
|
+
This previously used the keyword `from`, and this keyword is deprecated.
|
243
|
+
|
253
244
|
### Syncing attributes
|
254
245
|
|
255
246
|
There's a down side to keeping some things internal to this settings attribute. You can query JSON types in postgres,
|
@@ -260,9 +251,9 @@ Let's say we want to be able to be able to easily query users who have opted in.
|
|
260
251
|
leave it, as the case may be) on the users table.
|
261
252
|
|
262
253
|
```ruby
|
263
|
-
|
264
|
-
|
265
|
-
|
254
|
+
attribute_schema :settings do
|
255
|
+
field :email_list_beginner, :boolean, default: true, sync: :opted_in
|
256
|
+
end
|
266
257
|
```
|
267
258
|
|
268
259
|
```ruby
|
@@ -281,7 +272,6 @@ things in sync easier. The second issue can arise is when this attribute is set
|
|
281
272
|
using things like `user.update_column(:opted_in, false)`, and `User.update_all(opted_in: false)` will allow things to
|
282
273
|
get out of sync.
|
283
274
|
|
284
|
-
|
285
275
|
## Querying a JSON column
|
286
276
|
|
287
277
|
This has come up a little bit, and so it's worth documenting -- though it has very little to do with Schemattr. When you
|
@@ -292,16 +282,17 @@ these are the common scenarios that we've used.
|
|
292
282
|
|
293
283
|
```
|
294
284
|
User.where("(settings->>'opted_in')::boolean") # boolean query
|
295
|
-
User.where("settings->>'string_value' = ?", "some string") # string query
|
285
|
+
User.where("settings->>'string_value' = ?", "some string") # string query
|
296
286
|
```
|
297
287
|
|
298
|
-
|
299
288
|
## License
|
300
289
|
|
301
|
-
|
290
|
+
This project is released under the MIT license:
|
302
291
|
|
303
|
-
|
292
|
+
* https://opensource.org/licenses/MIT
|
304
293
|
|
294
|
+
Copyright 2023 [jejacks0n](https://github.com/jejacks0n)
|
305
295
|
|
306
296
|
## Make Code Not War
|
307
|
-
|
297
|
+
|
298
|
+
[](http://forthebadge.com)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Schemattr
|
2
4
|
module ActiveRecordExtension
|
3
5
|
module ClassMethods
|
@@ -23,7 +25,7 @@ module Schemattr
|
|
23
25
|
end
|
24
26
|
|
25
27
|
define_method "#{name}" do
|
26
|
-
|
28
|
+
schemaless_attributes[name] ||= attribute_schema.attribute_class.new(self, name, options[:strict] == false)
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
@@ -33,14 +35,13 @@ module Schemattr
|
|
33
35
|
end
|
34
36
|
|
35
37
|
def reload(*_args)
|
36
|
-
|
38
|
+
schemaless_attributes.keys.each { |name| schemaless_attributes[name] = nil }
|
37
39
|
super
|
38
40
|
end
|
39
41
|
|
40
42
|
private
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
43
|
+
def schemaless_attributes
|
44
|
+
@_schemaless_attributes ||= {}
|
45
|
+
end
|
45
46
|
end
|
46
47
|
end
|
data/lib/schemattr/attribute.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Schemattr
|
2
4
|
class Attribute
|
3
5
|
attr_accessor :model, :attr_name, :hash
|
@@ -22,39 +24,38 @@ module Schemattr
|
|
22
24
|
end
|
23
25
|
|
24
26
|
private
|
27
|
+
def method_missing(m, *args)
|
28
|
+
if @allow_arbitrary_attributes
|
29
|
+
self[$1] = args[0] if args.length == 1 && /^(\w+)=$/ =~ m
|
30
|
+
self[m.to_s.gsub(/\?$/, "")]
|
31
|
+
else
|
32
|
+
raise NoMethodError, "undefined method '#{m}' for #{self.class}"
|
33
|
+
end
|
34
|
+
end
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
36
|
+
def migrate_value(val, from)
|
37
|
+
return val unless from
|
38
|
+
if (old_val = self[from]).nil?
|
39
|
+
val
|
40
|
+
else
|
41
|
+
@hash.delete(from.to_s)
|
42
|
+
old_val
|
43
|
+
end
|
32
44
|
end
|
33
|
-
end
|
34
45
|
|
35
|
-
|
36
|
-
|
37
|
-
if (old_val = self[from]).nil?
|
46
|
+
def sync_value(val, to)
|
47
|
+
model[to] = val if to
|
38
48
|
val
|
39
|
-
else
|
40
|
-
@hash.delete(from.to_s)
|
41
|
-
old_val
|
42
49
|
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def sync_value(val, to)
|
46
|
-
model[to] = val if to
|
47
|
-
val
|
48
|
-
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
def []=(key, val)
|
52
|
+
hash[key.to_s] = val
|
53
|
+
model[attr_name] = hash
|
54
|
+
val
|
55
|
+
end
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
def [](key)
|
58
|
+
hash[key.to_s]
|
59
|
+
end
|
59
60
|
end
|
60
61
|
end
|
data/lib/schemattr/dsl.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Schemattr
|
2
4
|
class DSL
|
3
5
|
attr_accessor :attribute_class, :delegated, :defaults
|
@@ -13,74 +15,83 @@ module Schemattr
|
|
13
15
|
end
|
14
16
|
|
15
17
|
protected
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
def field(name, type, options = {})
|
19
|
+
if options[:from].present?
|
20
|
+
options[:value_from] = options.delete(:from)
|
21
|
+
log_warning(name, type, options[:value_from])
|
22
|
+
end
|
23
|
+
|
24
|
+
if respond_to?(type, true)
|
25
|
+
send(type, name, options)
|
26
|
+
else
|
27
|
+
define(name, false, options)
|
28
|
+
end
|
22
29
|
end
|
23
|
-
end
|
24
30
|
|
25
|
-
|
26
|
-
|
27
|
-
|
31
|
+
def string(name, options = {})
|
32
|
+
define name, false, options, setter: lambda { |val| sync_value(self[name] = val.to_s, options[:sync]) }
|
33
|
+
end
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
35
|
+
def integer(name, options = {})
|
36
|
+
define name, false, options, setter: lambda { |val| sync_value(self[name] = val.to_i, options[:sync]) }
|
37
|
+
end
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
|
39
|
+
def float(name, options = {})
|
40
|
+
define name, false, options, setter: lambda { |val| sync_value(self[name] = val.to_f, options[:sync]) }
|
41
|
+
end
|
36
42
|
|
37
|
-
|
38
|
-
|
39
|
-
|
43
|
+
def datetime(name, options = {})
|
44
|
+
define name, false, options
|
45
|
+
end
|
40
46
|
|
41
|
-
|
42
|
-
|
43
|
-
|
47
|
+
def date(name, options = {})
|
48
|
+
define name, false, options
|
49
|
+
end
|
44
50
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
+
def boolean(name, options = {})
|
52
|
+
define name, true, options, setter: lambda { |val|
|
53
|
+
bool = ActiveRecord::Type::Boolean.new.deserialize(val)
|
54
|
+
sync_value(self[name] = bool, options[:sync])
|
55
|
+
}
|
56
|
+
end
|
51
57
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
58
|
+
alias_method :text, :string
|
59
|
+
alias_method :bigint, :integer
|
60
|
+
alias_method :decimal, :float
|
61
|
+
alias_method :time, :datetime
|
56
62
|
|
57
63
|
private
|
64
|
+
def define(name, boolean, options, blocks = {})
|
65
|
+
setter = blocks[:setter] || lambda { sync_value(self[name] = val, options[:sync]) }
|
66
|
+
getter = blocks[:getter] || lambda { migrate_value(self[name], options[:value_from]) }
|
67
|
+
default_for(name, options[:default])
|
68
|
+
method_for("#{name}=", options[:sync], &setter)
|
69
|
+
method_for(name, options[:sync], &getter)
|
70
|
+
alias_for("#{name}?", name, options[:sync]) if boolean
|
71
|
+
end
|
58
72
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
_default(name, options[:default])
|
63
|
-
_method("#{name}=", options[:sync], &setter)
|
64
|
-
_method(name, options[:sync], &getter)
|
65
|
-
_alias("#{name}?", name, options[:sync]) if boolean
|
66
|
-
end
|
73
|
+
def default_for(name, default)
|
74
|
+
@defaults[name.to_s] = default
|
75
|
+
end
|
67
76
|
|
68
|
-
|
69
|
-
|
70
|
-
|
77
|
+
def log_warning(name, type, old_name)
|
78
|
+
message = <<-HEREDOC
|
79
|
+
Schemattr Warning: #{name}, #{type}, from: #{old_name}
|
80
|
+
You are using the keyword `from:` instead of the new `value_from:`. This is deprecated and will be removed in a future version."
|
81
|
+
HEREDOC
|
82
|
+
puts message
|
83
|
+
end
|
71
84
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
85
|
+
def method_for(name, delegated = false, &block)
|
86
|
+
@delegated.push(name.to_s) if delegated
|
87
|
+
unless attribute_class.instance_methods.include?(name.to_sym)
|
88
|
+
attribute_class.send(:define_method, name, &block)
|
89
|
+
end
|
76
90
|
end
|
77
|
-
end
|
78
91
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
attribute_class.send(:alias_method, new, old)
|
92
|
+
def alias_for(new, old, delegated)
|
93
|
+
@delegated.push(new.to_s) if delegated
|
94
|
+
attribute_class.send(:alias_method, new, old) unless attribute_class.instance_methods.include?(new.to_sym)
|
83
95
|
end
|
84
|
-
end
|
85
96
|
end
|
86
97
|
end
|
data/lib/schemattr/version.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Schemattr
|
2
|
-
|
4
|
+
# Returns the currently loaded version as a +Gem::Version+.
|
5
|
+
def self.version
|
6
|
+
Gem::Version.new(VERSION::STRING)
|
7
|
+
end
|
8
|
+
|
9
|
+
module VERSION
|
10
|
+
MAJOR = 0
|
11
|
+
MINOR = 2
|
12
|
+
TINY = 0
|
13
|
+
PRE = nil
|
14
|
+
|
15
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
16
|
+
end
|
3
17
|
end
|
data/lib/schemattr.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "schemattr/version"
|
2
4
|
require "schemattr/dsl"
|
3
5
|
require "schemattr/attribute"
|
4
|
-
require "schemattr/active_record_extension
|
6
|
+
require "schemattr/active_record_extension"
|
5
7
|
|
6
8
|
ActiveRecord::Base.send(:include, Schemattr::ActiveRecordExtension) if defined?(ActiveRecord)
|
metadata
CHANGED
@@ -1,34 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: schemattr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
autorequire:
|
7
|
+
- Jeremy Jackson
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
date: 2023-07-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.0.0
|
27
|
+
description: Write schema-less attributes in ActiveRecord using a helpful and flexible
|
28
|
+
DSL.
|
29
|
+
email: jejacks0n@gmail.com
|
16
30
|
executables: []
|
17
31
|
extensions: []
|
18
32
|
extra_rdoc_files: []
|
19
33
|
files:
|
20
|
-
-
|
34
|
+
- CHANGELOG.md
|
35
|
+
- MIT-LICENSE
|
21
36
|
- README.md
|
22
37
|
- lib/schemattr.rb
|
23
38
|
- lib/schemattr/active_record_extension.rb
|
24
39
|
- lib/schemattr/attribute.rb
|
25
40
|
- lib/schemattr/dsl.rb
|
26
41
|
- lib/schemattr/version.rb
|
27
|
-
homepage: https://github.com/
|
42
|
+
homepage: https://github.com/jejacks0n/schemattr
|
28
43
|
licenses:
|
29
44
|
- MIT
|
30
|
-
metadata:
|
31
|
-
|
45
|
+
metadata:
|
46
|
+
homepage_uri: https://github.com/jejacks0n/schemattr
|
47
|
+
source_code_uri: https://github.com/jejacks0n/schemattr
|
48
|
+
bug_tracker_uri: https://github.com/jejacks0n/schemattr/issues
|
49
|
+
changelog_uri: https://github.com/jejacks0n/schemattr/CHANGELOG.md
|
50
|
+
documentation_uri: https://github.com/jejacks0n/schemattr/README.md
|
51
|
+
rubygems_mfa_required: 'true'
|
52
|
+
post_install_message:
|
32
53
|
rdoc_options: []
|
33
54
|
require_paths:
|
34
55
|
- lib
|
@@ -36,16 +57,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
36
57
|
requirements:
|
37
58
|
- - ">="
|
38
59
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
60
|
+
version: 2.7.0
|
40
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
62
|
requirements:
|
42
63
|
- - ">="
|
43
64
|
- !ruby/object:Gem::Version
|
44
65
|
version: '0'
|
45
66
|
requirements: []
|
46
|
-
|
47
|
-
|
48
|
-
signing_key:
|
67
|
+
rubygems_version: 3.4.14
|
68
|
+
signing_key:
|
49
69
|
specification_version: 4
|
50
|
-
summary: ''
|
70
|
+
summary: 'Schemattr: Simple schema-less column definitions for ActiveRecord.'
|
51
71
|
test_files: []
|