active_record_properties 0.1.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 +7 -0
- data/CHANGELOG.md +23 -0
- data/LICENSE.txt +21 -0
- data/README.md +270 -0
- data/lib/active_record_properties/dsl.rb +27 -0
- data/lib/active_record_properties/property.rb +33 -0
- data/lib/active_record_properties/settable.rb +82 -0
- data/lib/active_record_properties/version.rb +5 -0
- data/lib/active_record_properties.rb +10 -0
- metadata +222 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3c559ee1c0fcde4e5d30fcf9c2886c92a83b05d9b64acec12befd19620f452ba
|
|
4
|
+
data.tar.gz: 19da1cdd203d63c27fc96ad3079dd41716a35ebfc2547f5b39171f016f70a774
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 378acd7972f525dc79897ab68e5b831e834697b942545ec1e66d4eca8c4d613b1333431d1c857f4fca2b638ec4c7a961a7b7dc56b26ff51c55248005811dbb2b
|
|
7
|
+
data.tar.gz: b05440aea8f698538a48fb8a72a1c8519afdbc42ecf2572c313ec0efd2bdbbf3b846f11ed688b925c5e4c97f5e1ff9150c66c5456c0beb6460c55019737035cd
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-02-08
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Initial release
|
|
14
|
+
- `ActiveRecordProperties::Settable` concern for adding properties to ActiveRecord models
|
|
15
|
+
- `has_properties` DSL for defining properties stored in JSONB columns
|
|
16
|
+
- Support for types: string, integer, float, boolean, hash, array
|
|
17
|
+
- Static and dynamic (proc) default values
|
|
18
|
+
- Automatic initialization of defaults via `after_initialize` callback
|
|
19
|
+
- Full test coverage with RSpec (28 examples, 0 failures)
|
|
20
|
+
- Support for Rails 7.0+, 7.1+, 7.2+, 8.0+, 8.1+
|
|
21
|
+
- Appraisal configuration for testing against multiple Rails versions
|
|
22
|
+
- Lefthook configuration for pre-commit hooks (rubocop, rspec, appraisal)
|
|
23
|
+
- Comprehensive README with usage examples and comparison table
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexey Poimtsev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# ActiveRecordProperties
|
|
2
|
+
|
|
3
|
+
Type-safe properties stored in JSONB for ActiveRecord models. A modern, lightweight alternative to separate settings tables.
|
|
4
|
+
|
|
5
|
+
## Why ActiveRecordProperties?
|
|
6
|
+
|
|
7
|
+
Store model settings and properties in a JSONB column with:
|
|
8
|
+
|
|
9
|
+
- **Clean DSL** - Simple, readable property definitions
|
|
10
|
+
- **Type Safety** - Built-in type casting for common types
|
|
11
|
+
- **Default Values** - Static or dynamic (proc) defaults
|
|
12
|
+
- **Performance** - No JOINs, everything in one table
|
|
13
|
+
- **Flexibility** - Use any JSONB column name
|
|
14
|
+
- **Rails-native** - Built on `store_accessor` and `attribute` APIs
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Add to your Gemfile:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
gem "active_record_properties"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Then run:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bundle install
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### 1. Add JSONB column to your model
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
class AddPropertiesToUsers < ActiveRecord::Migration[7.0]
|
|
36
|
+
def change
|
|
37
|
+
add_column :users, :properties, :jsonb, default: {}, null: false
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Include the module and define properties
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
class User < ApplicationRecord
|
|
46
|
+
include ActiveRecordProperties::Settable
|
|
47
|
+
|
|
48
|
+
has_properties do # Uses :properties column by default
|
|
49
|
+
property :theme, type: :string, default: "light"
|
|
50
|
+
property :language, type: :string, default: "en"
|
|
51
|
+
property :notifications_enabled, type: :boolean, default: true
|
|
52
|
+
property :email_frequency, type: :string, default: "daily"
|
|
53
|
+
property :preferences, type: :hash, default: -> { {} }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 3. Use like normal attributes
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
user = User.new
|
|
62
|
+
user.theme # => "light"
|
|
63
|
+
user.theme = "dark"
|
|
64
|
+
user.notifications_enabled # => true
|
|
65
|
+
user.preferences # => {}
|
|
66
|
+
user.save!
|
|
67
|
+
|
|
68
|
+
# All stored in JSONB
|
|
69
|
+
user.properties
|
|
70
|
+
# => {"theme"=>"dark", "language"=>"en", "notifications_enabled"=>true, ...}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
### Supported Types
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
has_properties do
|
|
79
|
+
property :name, type: :string, default: "default"
|
|
80
|
+
property :count, type: :integer, default: 0
|
|
81
|
+
property :rate, type: :float, default: 1.5
|
|
82
|
+
property :enabled, type: :boolean, default: true
|
|
83
|
+
property :config, type: :hash, default: -> { {} }
|
|
84
|
+
property :tags, type: :array, default: -> { [] }
|
|
85
|
+
end
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Static vs Dynamic Defaults
|
|
89
|
+
|
|
90
|
+
**Static defaults** (for immutable values):
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
property :tax_rate, type: :float, default: 13.0
|
|
94
|
+
property :enabled, type: :boolean, default: true
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Dynamic defaults** (for mutable values - use proc):
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
property :settings, type: :hash, default: -> { {} }
|
|
101
|
+
property :tags, type: :array, default: -> { [] }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
⚠️ **Important**: Always use proc for Hash and Array defaults to avoid sharing the same object between instances!
|
|
105
|
+
|
|
106
|
+
### Custom Column Name
|
|
107
|
+
|
|
108
|
+
By default, `has_properties` uses the `:properties` column. You can specify a different column name:
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
has_properties column: :settings do
|
|
112
|
+
property :foo, type: :string
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Defaults to :properties if column is not specified
|
|
116
|
+
has_properties do
|
|
117
|
+
property :bar, type: :string
|
|
118
|
+
end
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Multiple Property Groups
|
|
122
|
+
|
|
123
|
+
You can use multiple JSONB columns for different purposes:
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
class Organization < ApplicationRecord
|
|
127
|
+
include ActiveRecordProperties::Settable
|
|
128
|
+
|
|
129
|
+
has_properties column: :settings do
|
|
130
|
+
property :income_tax_rate, type: :float, default: 13.0
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
has_properties column: :preferences do
|
|
134
|
+
property :theme, type: :string, default: "light"
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Querying
|
|
140
|
+
|
|
141
|
+
Use PostgreSQL JSONB operators:
|
|
142
|
+
|
|
143
|
+
```ruby
|
|
144
|
+
# Find organizations with specific tax rate
|
|
145
|
+
Organization.where("settings->>'income_tax_rate' = ?", "13.0")
|
|
146
|
+
|
|
147
|
+
# Find organizations with auto-calculation enabled
|
|
148
|
+
Organization.where("settings->>'auto_calculate_net_salary' = ?", "true")
|
|
149
|
+
|
|
150
|
+
# Use JSONB containment
|
|
151
|
+
Organization.where("settings @> ?", {enabled: true}.to_json)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Examples
|
|
155
|
+
|
|
156
|
+
### User Preferences
|
|
157
|
+
|
|
158
|
+
```ruby
|
|
159
|
+
class User < ApplicationRecord
|
|
160
|
+
include ActiveRecordProperties::Settable
|
|
161
|
+
|
|
162
|
+
has_properties do # Uses :properties column by default
|
|
163
|
+
property :theme, type: :string, default: "light"
|
|
164
|
+
property :language, type: :string, default: "en"
|
|
165
|
+
property :notifications_enabled, type: :boolean, default: true
|
|
166
|
+
property :email_frequency, type: :string, default: "daily"
|
|
167
|
+
property :timezone, type: :string, default: "UTC"
|
|
168
|
+
property :ui_preferences, type: :hash, default: -> { {} }
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def notification_time
|
|
172
|
+
Time.current.in_time_zone(timezone)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Usage
|
|
177
|
+
user = User.create(theme: "dark", language: "ru")
|
|
178
|
+
user.theme # => "dark"
|
|
179
|
+
user.timezone = "Europe/Moscow"
|
|
180
|
+
user.notification_time # => Time in Moscow timezone
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Organization Settings
|
|
184
|
+
|
|
185
|
+
```ruby
|
|
186
|
+
class Organization < ApplicationRecord
|
|
187
|
+
include ActiveRecordProperties::Settable
|
|
188
|
+
|
|
189
|
+
has_properties column: :settings do
|
|
190
|
+
property :income_tax_rate, type: :float, default: 13.0
|
|
191
|
+
property :auto_calculate_net_salary, type: :boolean, default: true
|
|
192
|
+
property :requires_manager_approval, type: :boolean, default: true
|
|
193
|
+
property :requires_hrd_approval, type: :boolean, default: true
|
|
194
|
+
property :probation_period_months, type: :integer, default: 3
|
|
195
|
+
property :dashboard_period, type: :integer, default: 30
|
|
196
|
+
property :notification_settings, type: :hash, default: -> { {} }
|
|
197
|
+
property :kpi_targets, type: :hash, default: -> { {} }
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def calculate_net_from_gross(gross_amount)
|
|
201
|
+
return nil unless gross_amount && auto_calculate_net_salary
|
|
202
|
+
|
|
203
|
+
tax_multiplier = (100 - income_tax_rate) / 100.0
|
|
204
|
+
(gross_amount * tax_multiplier).round(2)
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Usage
|
|
209
|
+
org = Organization.create(income_tax_rate: 15.0)
|
|
210
|
+
org.calculate_net_from_gross(100_000) # => 85000.0
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Comparison with Alternatives
|
|
214
|
+
|
|
215
|
+
| Feature | ActiveRecordProperties | rails-settings-cached | ledermann/rails-settings |
|
|
216
|
+
| ----------- | ---------------------- | --------------------- | ------------------------ |
|
|
217
|
+
| Storage | JSONB column | Separate table | Separate table |
|
|
218
|
+
| Performance | Fast (no JOIN) | Slower (JOIN) | Slower (JOIN) |
|
|
219
|
+
| Setup | Include module | Global model | Polymorphic model |
|
|
220
|
+
| API | `org.setting` | `Setting.foo` | `org.settings(:key).foo` |
|
|
221
|
+
| Per-model | ✅ Yes | ❌ No (global) | ✅ Yes |
|
|
222
|
+
| Type safety | ✅ Yes | ✅ Yes | ⚠️ Limited |
|
|
223
|
+
| Defaults | ✅ Static + Dynamic | ✅ Yes | ✅ Yes |
|
|
224
|
+
|
|
225
|
+
## Rails Compatibility
|
|
226
|
+
|
|
227
|
+
Tested with:
|
|
228
|
+
|
|
229
|
+
- Rails 7.0
|
|
230
|
+
- Rails 7.1
|
|
231
|
+
- Rails 7.2
|
|
232
|
+
- Rails 8.0
|
|
233
|
+
- Rails 8.1
|
|
234
|
+
|
|
235
|
+
Ruby 3.2+ required.
|
|
236
|
+
|
|
237
|
+
## Development
|
|
238
|
+
|
|
239
|
+
After checking out the repo:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
bin/setup # Install dependencies
|
|
243
|
+
rake spec # Run tests
|
|
244
|
+
bin/console # Interactive prompt
|
|
245
|
+
bundle exec appraisal install # Install for all Rails versions
|
|
246
|
+
bundle exec appraisal rake spec # Test all Rails versions
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Running Tests
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
rake spec # Run all tests
|
|
253
|
+
bundle exec appraisal rake spec # Test against all Rails versions
|
|
254
|
+
bundle exec lefthook install # Install git hooks
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Code Quality
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
bundle exec rubocop # Check code style
|
|
261
|
+
bundle exec rubocop -A # Auto-fix issues
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Contributing
|
|
265
|
+
|
|
266
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/alec-c4/active_record_properties.
|
|
267
|
+
|
|
268
|
+
## License
|
|
269
|
+
|
|
270
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveRecordProperties
|
|
4
|
+
# DSL for defining properties
|
|
5
|
+
class DSL
|
|
6
|
+
attr_reader :properties, :column
|
|
7
|
+
|
|
8
|
+
def initialize(column)
|
|
9
|
+
@column = column
|
|
10
|
+
@properties = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Define a property
|
|
14
|
+
#
|
|
15
|
+
# @param name [Symbol, String] Property name
|
|
16
|
+
# @param type [Symbol] Property type (:string, :integer, :float, :boolean, :hash, :array)
|
|
17
|
+
# @param default [Object, Proc] Default value or proc
|
|
18
|
+
#
|
|
19
|
+
# @example
|
|
20
|
+
# property :income_tax_rate, type: :float, default: 13.0
|
|
21
|
+
# property :settings, type: :hash, default: -> { {} }
|
|
22
|
+
def property(name, type: :string, default: nil)
|
|
23
|
+
prop = Property.new(name, type: type, default: default, column: column)
|
|
24
|
+
@properties << prop
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveRecordProperties
|
|
4
|
+
# Represents a single property definition
|
|
5
|
+
class Property
|
|
6
|
+
attr_reader :name, :type, :default, :column
|
|
7
|
+
|
|
8
|
+
SUPPORTED_TYPES = %i[string integer float boolean hash array].freeze
|
|
9
|
+
|
|
10
|
+
def initialize(name, type: :string, default: nil, column: :properties)
|
|
11
|
+
@name = name.to_sym
|
|
12
|
+
@type = type.to_sym
|
|
13
|
+
@default = default
|
|
14
|
+
@column = column.to_sym
|
|
15
|
+
|
|
16
|
+
validate_type!
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def default_value
|
|
20
|
+
return default.call if default.respond_to?(:call)
|
|
21
|
+
default
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def validate_type!
|
|
27
|
+
return if SUPPORTED_TYPES.include?(type)
|
|
28
|
+
|
|
29
|
+
raise ArgumentError, "Unsupported type: #{type}. " \
|
|
30
|
+
"Supported types: #{SUPPORTED_TYPES.join(", ")}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/concern"
|
|
4
|
+
|
|
5
|
+
module ActiveRecordProperties
|
|
6
|
+
# Main concern for adding properties to ActiveRecord models
|
|
7
|
+
module Settable
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
class_methods do
|
|
11
|
+
# Define properties stored in JSONB column
|
|
12
|
+
#
|
|
13
|
+
# @param column [Symbol] Name of JSONB column (default: :properties)
|
|
14
|
+
# @param block [Proc] Block with property definitions
|
|
15
|
+
#
|
|
16
|
+
# @example
|
|
17
|
+
# class Organization < ApplicationRecord
|
|
18
|
+
# include ActiveRecordProperties::Settable
|
|
19
|
+
#
|
|
20
|
+
# has_properties column: :settings do
|
|
21
|
+
# property :income_tax_rate, type: :float, default: 13.0
|
|
22
|
+
# property :auto_calculate_net_salary, type: :boolean, default: true
|
|
23
|
+
# property :probation_period_months, type: :integer, default: 3
|
|
24
|
+
# property :notification_settings, type: :hash, default: -> { {} }
|
|
25
|
+
# end
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# org = Organization.new
|
|
29
|
+
# org.income_tax_rate # => 13.0
|
|
30
|
+
# org.income_tax_rate = 15.0
|
|
31
|
+
def has_properties(column: :properties, &block)
|
|
32
|
+
dsl = DSL.new(column)
|
|
33
|
+
dsl.instance_eval(&block)
|
|
34
|
+
|
|
35
|
+
setup_properties(column, dsl.properties)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def setup_properties(column, properties)
|
|
41
|
+
# Setup store_accessor for JSONB column
|
|
42
|
+
accessor_names = properties.map(&:name)
|
|
43
|
+
store_accessor column, *accessor_names
|
|
44
|
+
|
|
45
|
+
# Store properties metadata for introspection
|
|
46
|
+
class_variable_set(:@@_properties, properties)
|
|
47
|
+
class_variable_set(:@@_properties_column, column)
|
|
48
|
+
|
|
49
|
+
# Initialize defaults via callback
|
|
50
|
+
after_initialize do
|
|
51
|
+
column_data = send(column) || {}
|
|
52
|
+
|
|
53
|
+
properties.each do |property|
|
|
54
|
+
# Only set default if value is not already set
|
|
55
|
+
next if column_data.key?(property.name.to_s)
|
|
56
|
+
|
|
57
|
+
default_val = property.default_value
|
|
58
|
+
send("#{property.name}=", default_val) unless default_val.nil?
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Get all defined properties
|
|
65
|
+
#
|
|
66
|
+
# @return [Array<Property>] Array of property definitions
|
|
67
|
+
def self.properties
|
|
68
|
+
return [] unless class_variable_defined?(:@@_properties)
|
|
69
|
+
|
|
70
|
+
class_variable_get(:@@_properties)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Get properties column name
|
|
74
|
+
#
|
|
75
|
+
# @return [Symbol] Column name
|
|
76
|
+
def self.properties_column
|
|
77
|
+
return :properties unless class_variable_defined?(:@@_properties_column)
|
|
78
|
+
|
|
79
|
+
class_variable_get(:@@_properties_column)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "active_record_properties/version"
|
|
4
|
+
require_relative "active_record_properties/property"
|
|
5
|
+
require_relative "active_record_properties/dsl"
|
|
6
|
+
require_relative "active_record_properties/settable"
|
|
7
|
+
|
|
8
|
+
module ActiveRecordProperties
|
|
9
|
+
class Error < StandardError; end
|
|
10
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: active_record_properties
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Alexey Poimtsev
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activerecord
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: activesupport
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '7.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '7.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: bundler
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '2.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '2.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rake
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '13.0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '13.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rspec
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '3.0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '3.0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: simplecov
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0.21'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0.21'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: appraisal
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: lefthook
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - ">="
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0'
|
|
124
|
+
- !ruby/object:Gem::Dependency
|
|
125
|
+
name: sqlite3
|
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - "~>"
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '2.0'
|
|
131
|
+
type: :development
|
|
132
|
+
prerelease: false
|
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - "~>"
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '2.0'
|
|
138
|
+
- !ruby/object:Gem::Dependency
|
|
139
|
+
name: rubocop-rspec
|
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - ">="
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '0'
|
|
145
|
+
type: :development
|
|
146
|
+
prerelease: false
|
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - ">="
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '0'
|
|
152
|
+
- !ruby/object:Gem::Dependency
|
|
153
|
+
name: rubocop-performance
|
|
154
|
+
requirement: !ruby/object:Gem::Requirement
|
|
155
|
+
requirements:
|
|
156
|
+
- - ">="
|
|
157
|
+
- !ruby/object:Gem::Version
|
|
158
|
+
version: '0'
|
|
159
|
+
type: :development
|
|
160
|
+
prerelease: false
|
|
161
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
162
|
+
requirements:
|
|
163
|
+
- - ">="
|
|
164
|
+
- !ruby/object:Gem::Version
|
|
165
|
+
version: '0'
|
|
166
|
+
- !ruby/object:Gem::Dependency
|
|
167
|
+
name: standard
|
|
168
|
+
requirement: !ruby/object:Gem::Requirement
|
|
169
|
+
requirements:
|
|
170
|
+
- - ">="
|
|
171
|
+
- !ruby/object:Gem::Version
|
|
172
|
+
version: 1.35.1
|
|
173
|
+
type: :development
|
|
174
|
+
prerelease: false
|
|
175
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
176
|
+
requirements:
|
|
177
|
+
- - ">="
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: 1.35.1
|
|
180
|
+
description: Store model settings and properties in JSONB columns with a clean DSL,
|
|
181
|
+
type casting, default values, and validations. A modern alternative to separate
|
|
182
|
+
settings tables.
|
|
183
|
+
email:
|
|
184
|
+
- alexey.poimtsev@gmail.com
|
|
185
|
+
executables: []
|
|
186
|
+
extensions: []
|
|
187
|
+
extra_rdoc_files: []
|
|
188
|
+
files:
|
|
189
|
+
- CHANGELOG.md
|
|
190
|
+
- LICENSE.txt
|
|
191
|
+
- README.md
|
|
192
|
+
- lib/active_record_properties.rb
|
|
193
|
+
- lib/active_record_properties/dsl.rb
|
|
194
|
+
- lib/active_record_properties/property.rb
|
|
195
|
+
- lib/active_record_properties/settable.rb
|
|
196
|
+
- lib/active_record_properties/version.rb
|
|
197
|
+
homepage: https://github.com/alec-c4/active_record_properties
|
|
198
|
+
licenses:
|
|
199
|
+
- MIT
|
|
200
|
+
metadata:
|
|
201
|
+
homepage_uri: https://github.com/alec-c4/active_record_properties
|
|
202
|
+
source_code_uri: https://github.com/alec-c4/active_record_properties
|
|
203
|
+
changelog_uri: https://github.com/alec-c4/active_record_properties/blob/main/CHANGELOG.md
|
|
204
|
+
rubygems_mfa_required: 'true'
|
|
205
|
+
rdoc_options: []
|
|
206
|
+
require_paths:
|
|
207
|
+
- lib
|
|
208
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
209
|
+
requirements:
|
|
210
|
+
- - ">="
|
|
211
|
+
- !ruby/object:Gem::Version
|
|
212
|
+
version: 3.2.0
|
|
213
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
|
+
requirements:
|
|
215
|
+
- - ">="
|
|
216
|
+
- !ruby/object:Gem::Version
|
|
217
|
+
version: '0'
|
|
218
|
+
requirements: []
|
|
219
|
+
rubygems_version: 4.0.6
|
|
220
|
+
specification_version: 4
|
|
221
|
+
summary: Type-safe properties stored in JSONB for ActiveRecord models
|
|
222
|
+
test_files: []
|