domainic-attributer 0.1.0 → 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/.yardopts +11 -0
- data/CHANGELOG.md +32 -1
- data/README.md +42 -355
- data/docs/USAGE.md +723 -0
- data/lib/domainic/attributer/attribute/callback.rb +21 -9
- data/lib/domainic/attributer/attribute/coercer.rb +28 -13
- data/lib/domainic/attributer/attribute/mixin/belongs_to_attribute.rb +16 -13
- data/lib/domainic/attributer/attribute/signature.rb +43 -32
- data/lib/domainic/attributer/attribute/validator.rb +46 -16
- data/lib/domainic/attributer/attribute.rb +28 -18
- data/lib/domainic/attributer/attribute_set.rb +21 -19
- data/lib/domainic/attributer/class_methods.rb +136 -83
- data/lib/domainic/attributer/dsl/attribute_builder/option_parser.rb +64 -22
- data/lib/domainic/attributer/dsl/attribute_builder.rb +515 -26
- data/lib/domainic/attributer/dsl/initializer.rb +23 -18
- data/lib/domainic/attributer/dsl/method_injector.rb +16 -14
- data/lib/domainic/attributer/errors/aggregate_error.rb +36 -0
- data/lib/domainic/attributer/errors/callback_execution_error.rb +30 -0
- data/lib/domainic/attributer/errors/coercion_execution_error.rb +37 -0
- data/lib/domainic/attributer/errors/error.rb +19 -0
- data/lib/domainic/attributer/errors/validation_execution_error.rb +30 -0
- data/lib/domainic/attributer/instance_methods.rb +11 -8
- data/lib/domainic/attributer/undefined.rb +9 -7
- data/lib/domainic/attributer.rb +88 -27
- data/sig/domainic/attributer/attribute/callback.rbs +10 -7
- data/sig/domainic/attributer/attribute/coercer.rbs +14 -11
- data/sig/domainic/attributer/attribute/mixin/belongs_to_attribute.rbs +14 -12
- data/sig/domainic/attributer/attribute/signature.rbs +43 -32
- data/sig/domainic/attributer/attribute/validator.rbs +28 -13
- data/sig/domainic/attributer/attribute.rbs +27 -17
- data/sig/domainic/attributer/attribute_set.rbs +21 -19
- data/sig/domainic/attributer/class_methods.rbs +133 -80
- data/sig/domainic/attributer/dsl/attribute_builder/option_parser.rbs +62 -22
- data/sig/domainic/attributer/dsl/attribute_builder.rbs +515 -26
- data/sig/domainic/attributer/dsl/initializer.rbs +21 -19
- data/sig/domainic/attributer/dsl/method_injector.rbs +16 -14
- data/sig/domainic/attributer/errors/aggregate_error.rbs +28 -0
- data/sig/domainic/attributer/errors/callback_execution_error.rbs +23 -0
- data/sig/domainic/attributer/errors/coercion_execution_error.rbs +29 -0
- data/sig/domainic/attributer/errors/error.rbs +17 -0
- data/sig/domainic/attributer/errors/validation_execution_error.rbs +23 -0
- data/sig/domainic/attributer/instance_methods.rbs +11 -8
- data/sig/domainic/attributer/undefined.rbs +5 -3
- data/sig/domainic/attributer.rbs +88 -27
- metadata +19 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 755badcda20958e3c9cb1855eb4c3b1fcd882b5784027a1a49a14cc92ce43f4e
|
|
4
|
+
data.tar.gz: 4f7ceafc636d5ec5c30612960d35446985fa538c6bcea0813226e9b23b87507d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1b9171dd305607ca3d0a7228652cb076c5672884897675da90acdbac02843133edfc77cb998f510be3b599e2066df06c7edce0e066a7bdaa6c9c5696838c49d1
|
|
7
|
+
data.tar.gz: 150433dd03367419bc7a3fbd1fe24e76d06f4633e043b530f3a2212927b2e3171fc3a62cccb52f69650a73168779856db73b3efcf9604592dccbdfb9a243dae6
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
|
@@ -6,9 +6,40 @@ The format is based on [Keep a Changelog], and this project adheres to [Break Ve
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [v0.2.0] - 2025-01-01
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
* [#22](https://github.com/domainic/domainic/pull/22) Specialized error classes (`ValidationExecutionError`,
|
|
14
|
+
`CallbackExecutionError`, and`CoercionExecutionError`) to provide clear error reporting for validation, callback,
|
|
15
|
+
and coercion failures.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
* [#18](https://github.com/domainic/domainic/pull/18) `Domainic::Attributer::Attribute::Coercer#call` will no longer
|
|
20
|
+
attempt to coerce nil values when the attribute is not nilable. While small this is technically a breaking change.
|
|
21
|
+
* [#169](https://github.com/domainic/domainic/pull/169) removed implicit dependency on RSpec from
|
|
22
|
+
`Domainic::Attributer::Attribute::BelongsToAttribute`
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
* [#18](https://github.com/domainic/domainic/pull/18) Fixed missing requires for `Domainic::Attributer::Undefined` in
|
|
27
|
+
the `Domainic::Attributer::Attribute` and `Domainic::Attributer::Attribute::Validator` classes.
|
|
28
|
+
* [#94](https://github.com/domainic/domainic/pull/94) Fixed missing requires for `Domainic::Attributer::Undefined` in
|
|
29
|
+
`Domainic::Attributer::DSL::OptionParser`, and `Domainic::Attributer::DSL::Initializer`
|
|
30
|
+
* [#94](https://github.com/domainic/domainic/pull/94) Fixed missing require for `Domainic::Attributer::Attribute` in
|
|
31
|
+
`Domainic::Attributer::Attribute::BelongsToAttribute`
|
|
32
|
+
* Various documentation improvements and corrections.
|
|
33
|
+
|
|
34
|
+
## [v0.1.0] - 2024-12-12
|
|
35
|
+
|
|
36
|
+
* Initial release
|
|
37
|
+
|
|
9
38
|
[Keep a Changelog]: https://keepachangelog.com/en/1.0.0/
|
|
10
39
|
[Break Versioning]: https://www.taoensso.com/break-versioning
|
|
11
40
|
|
|
12
41
|
<!-- versions -->
|
|
13
42
|
|
|
14
|
-
[Unreleased]: https://github.com/domainic/domainic/
|
|
43
|
+
[Unreleased]: https://github.com/domainic/domainic/compare/domainic-attributer-v0.2.0...HEAD
|
|
44
|
+
[v0.2.0]: https://github.com/domainic/domainic/compare/domainic-attributer-v0.1.0...domainic-attributer-v0.2.0
|
|
45
|
+
[v0.1.0]: https://github.com/domainic/domainic/compare/53f3e992ab0e3f0092fd842c4cf89c22e41afa8a...domainic-attributer-v0.1.0
|
data/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Domainic::Attributer
|
|
2
2
|
|
|
3
|
-
[](https://rubygems.org/gems/domainic-attributer)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
[](https://rubydoc.info/gems/domainic-attributer/0.1.0)
|
|
6
|
+
[](https://github.com/domainic/domainic/issues?q=state%3Aopen%20label%3Adomainic-attributer%20)
|
|
4
7
|
|
|
5
|
-
Domainic::Attributer is a powerful toolkit
|
|
6
|
-
|
|
7
|
-
type-safe, and well-behaved. Ever wished your class attributes could:
|
|
8
|
+
Domainic::Attributer is a powerful toolkit that brings clarity and safety to your Ruby class attributes.
|
|
9
|
+
Ever wished your class attributes could:
|
|
8
10
|
|
|
9
11
|
* Validate themselves to ensure they only accept correct values?
|
|
10
12
|
* Transform input data automatically into the right format?
|
|
@@ -13,384 +15,69 @@ type-safe, and well-behaved. Ever wished your class attributes could:
|
|
|
13
15
|
* Tell you when they change?
|
|
14
16
|
* Distinguish between required arguments and optional settings?
|
|
15
17
|
|
|
16
|
-
That's exactly what Domainic::Attributer does! It
|
|
17
|
-
|
|
18
|
-
type checking, and custom attribute methods, let Domainic::Attributer handle the heavy lifting while you focus on your
|
|
19
|
-
domain logic.
|
|
18
|
+
That's exactly what Domainic::Attributer does! It provides a declarative way to define and manage attributes
|
|
19
|
+
in your Ruby classes, ensuring data integrity and clear interfaces. It's particularly valuable for:
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
* Domain models and value objects
|
|
22
|
+
* Service objects and command patterns
|
|
23
|
+
* Configuration objects
|
|
24
|
+
* Any class where attribute behavior matters
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Add this line to your application's Gemfile:
|
|
27
|
-
|
|
28
|
-
```ruby
|
|
29
|
-
gem 'domainic-attributer'
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Or install it yourself as:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
gem install domainic-attributer
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Usage
|
|
26
|
+
Think of it as giving your attributes a brain - they know what they want, how they should behave, and
|
|
27
|
+
they're not afraid to speak up when something's not right!
|
|
39
28
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Getting started with Domainic::Attributer is as easy as including the module and declaring your attributes:
|
|
29
|
+
## Quick Start
|
|
43
30
|
|
|
44
31
|
```ruby
|
|
45
|
-
class
|
|
32
|
+
class SuperDev
|
|
46
33
|
include Domainic::Attributer
|
|
47
34
|
|
|
48
|
-
argument :
|
|
49
|
-
option :
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
person = Person.new("Alice", age: 30)
|
|
53
|
-
person.name # => "Alice"
|
|
54
|
-
person.age # => 30
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Arguments vs Options
|
|
58
|
-
|
|
59
|
-
Domainic::Attributer gives you two ways to define attributes:
|
|
60
|
-
|
|
61
|
-
* `argument`: Required positional parameters that must be provided in order
|
|
62
|
-
* `option`: Named parameters that can be provided in any order (and are optional by default)
|
|
63
|
-
|
|
64
|
-
```ruby
|
|
65
|
-
class Hero
|
|
66
|
-
include Domainic::Attributer
|
|
67
|
-
|
|
68
|
-
argument :name # Required, must be first
|
|
69
|
-
argument :power # Required, must be second
|
|
70
|
-
option :catchphrase # Optional, can be provided by name
|
|
71
|
-
option :sidekick # Optional, can be provided by name
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# All valid ways to create a hero:
|
|
75
|
-
Hero.new("Spider-Man", "Web-slinging", catchphrase: "With great power...")
|
|
76
|
-
Hero.new("Batman", "Being rich", sidekick: "Robin")
|
|
77
|
-
Hero.new("Wonder Woman", "Super strength")
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
#### Argument Ordering and Default Values
|
|
81
|
-
|
|
82
|
-
Arguments in Domainic::Attributer follow special ordering rules based on whether they have defaults:
|
|
83
|
-
|
|
84
|
-
* Arguments without defaults are required and are automatically moved to the front of the argument list
|
|
85
|
-
* Arguments with defaults are optional and are moved to the end of the argument list
|
|
86
|
-
* Within each group (with/without defaults), arguments maintain their order of declaration
|
|
87
|
-
|
|
88
|
-
This means the actual position when providing arguments to the constructor will be different from their declaration
|
|
89
|
-
order:
|
|
90
|
-
|
|
91
|
-
```ruby
|
|
92
|
-
class EmailMessage
|
|
93
|
-
include Domainic::Attributer
|
|
94
|
-
|
|
95
|
-
# This will be the first argument (no default)
|
|
96
|
-
argument :to
|
|
97
|
-
|
|
98
|
-
# This will be the third argument (has default)
|
|
99
|
-
argument :priority, default: :normal
|
|
100
|
-
|
|
101
|
-
# This will be the second argument (no default)
|
|
102
|
-
argument :subject
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# Arguments must be provided in their sorted order,
|
|
106
|
-
# with required arguments first:
|
|
107
|
-
EmailMessage.new("user@example.com", "Welcome!", :high)
|
|
108
|
-
# => #<EmailMessage:0x00007f9b1b8b3b10 @to="user@example.com", @priority=:high, @subject="Welcome!">
|
|
109
|
-
|
|
110
|
-
# If you try to provide the arguments in their declaration order, you'll get undesired results:
|
|
111
|
-
EmailMessage.new("user@example.com", :high, "Welcome!")
|
|
112
|
-
# => #<EmailMessage:0x00007f9b1b8b3b10 @to="user@example.com", @priority="Welcome!", @subject=:high>
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
This behavior ensures that required arguments are provided first and optional arguments (those with defaults) come
|
|
116
|
-
after, making argument handling more predictable. You can rely on this ordering regardless of how you declare the
|
|
117
|
-
arguments in your class. Best practice is to declare arguments without defaults first, followed by those with defaults.
|
|
35
|
+
argument :code_name, String
|
|
36
|
+
option :power_level, Integer, default: 9000
|
|
118
37
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
```ruby
|
|
124
|
-
class User
|
|
125
|
-
include Domainic::Attributer
|
|
126
|
-
|
|
127
|
-
argument :email do
|
|
128
|
-
non_nilable # or not_null, non_null, etc.
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
option :nickname do
|
|
132
|
-
default nil # Explicitly allow nil
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
Ensure certain options are always provided:
|
|
138
|
-
|
|
139
|
-
```ruby
|
|
140
|
-
class Order
|
|
141
|
-
include Domainic::Attributer
|
|
142
|
-
|
|
143
|
-
option :items, required: true
|
|
144
|
-
option :status, Symbol
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
Order.new(option: ['item1', 'item2']) # OK
|
|
148
|
-
Order.new(status: :pending) # Raises ArgumentError
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
#### Required vs NonNilable
|
|
152
|
-
|
|
153
|
-
`required` and `non_nilable` are similar but not identical. `required` means the option must be provided when the object
|
|
154
|
-
is created, while `non_nilable` means the option must not be nil. A `required` option can still be nil if it's provided.
|
|
155
|
-
|
|
156
|
-
```ruby
|
|
157
|
-
class User
|
|
158
|
-
include Domainic::Attributer
|
|
159
|
-
|
|
160
|
-
option :email, String do
|
|
161
|
-
required
|
|
38
|
+
option :favorite_gem do
|
|
39
|
+
validate_with ->(val) { val.to_s.end_with?('ruby') }
|
|
40
|
+
coerce_with ->(val) { val.to_s.downcase }
|
|
162
41
|
non_nilable
|
|
163
42
|
end
|
|
164
|
-
|
|
165
|
-
option :nickname, String do
|
|
166
|
-
required
|
|
167
|
-
end
|
|
168
43
|
end
|
|
169
44
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
user = User.new(email: 'example@example.com', nickname: 'example')
|
|
175
|
-
user.nickname = nil # OK
|
|
176
|
-
user.email = nil # Raises ArgumentError because email is non_nilable
|
|
45
|
+
dev = SuperDev.new('RubyNinja', favorite_gem: 'RAILS_RUBY')
|
|
46
|
+
dev.favorite_gem # => "rails_ruby"
|
|
47
|
+
dev.power_level = 9001
|
|
48
|
+
dev.power_level = 'over 9000' # Raises ArgumentError: invalid value for Integer
|
|
177
49
|
```
|
|
178
50
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
Keep your data clean with built-in type validation:
|
|
182
|
-
|
|
183
|
-
```ruby
|
|
184
|
-
class BankAccount
|
|
185
|
-
include Domainic::Attributer
|
|
186
|
-
|
|
187
|
-
argument :account_name, String # Direct class validation
|
|
188
|
-
argument :opened_at, Time # Another direct class example
|
|
189
|
-
option :balance, Integer, default: 0 # Combining class validation with defaults
|
|
190
|
-
option :status, ->(val) { [:active, :closed].include?(val) } # Custom validation
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
# Will raise ArgumentError:
|
|
194
|
-
BankAccount.new(:my_account_name, Time.now)
|
|
195
|
-
BankAccount.new("my_account_name", "not a time")
|
|
196
|
-
BankAccount.new("my_account_name", Time.now, balance: "not an integer")
|
|
197
|
-
BankAccount.new("my_account_name", Time.now, balance: 100, status: :not_included_in_the_allow_list)
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### Documentation
|
|
201
|
-
|
|
202
|
-
Make your attributes self-documenting:
|
|
203
|
-
|
|
204
|
-
```ruby
|
|
205
|
-
class Car
|
|
206
|
-
include Domainic::Attributer
|
|
207
|
-
|
|
208
|
-
argument :make, String do
|
|
209
|
-
desc "The make of the car"
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
argument :model, String do
|
|
213
|
-
description "The model of the car"
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
argument :year, ->(value) { value.is_a?(Integer) && value >= 1900 && value <= Time.now.year } do
|
|
217
|
-
description "The year the car was made"
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### Value Coercion
|
|
223
|
-
|
|
224
|
-
Transform input values automatically:
|
|
225
|
-
|
|
226
|
-
```ruby
|
|
227
|
-
class Temperature
|
|
228
|
-
include Domainic::Attributer
|
|
229
|
-
|
|
230
|
-
argument :celsius do |value|
|
|
231
|
-
coerce_with ->(val) { val.to_f }
|
|
232
|
-
validate_with ->(val) { val.is_a?(Float) }
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
option :unit, default: "C" do |value|
|
|
236
|
-
validate_with ->(val) { ["C", "F"].include?(val) }
|
|
237
|
-
end
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
temp = Temperature.new("24.5") # Automatically converted to Float
|
|
241
|
-
temp.celsius # => 24.5
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### Custom Validation
|
|
245
|
-
|
|
246
|
-
Domainic::Attributer provides flexible validation options that can be combined to create sophisticated validation rules.
|
|
247
|
-
You can:
|
|
248
|
-
|
|
249
|
-
* Use Ruby classes directly to validate types
|
|
250
|
-
* Use Procs/lambdas for custom validation logic
|
|
251
|
-
* Chain multiple validations
|
|
252
|
-
* Combine validations with coercions
|
|
253
|
-
|
|
254
|
-
```ruby
|
|
255
|
-
class BankTransfer
|
|
256
|
-
include Domainic::Attributer
|
|
257
|
-
|
|
258
|
-
# Combine coercion and multiple validations
|
|
259
|
-
argument :amount do
|
|
260
|
-
coerce_with ->(val) { val.to_f } # First coerce to float
|
|
261
|
-
validate_with Float # Then validate it's a float
|
|
262
|
-
validate_with ->(val) { val.positive? } # And validate it's positive
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
# Different validation styles
|
|
266
|
-
argument :status do
|
|
267
|
-
validate_with Symbol # Must be a Symbol
|
|
268
|
-
validate_with ->(val) { [:pending, :completed, :failed].include?(val) } # Must be one of these values
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
# Validation with custom error handling
|
|
272
|
-
argument :reference_number do
|
|
273
|
-
validate_with ->(val) {
|
|
274
|
-
raise ArgumentError, "Reference must be 8 characters" unless val.length == 8
|
|
275
|
-
true
|
|
276
|
-
}
|
|
277
|
-
end
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
# These will work:
|
|
281
|
-
BankTransfer.new("50.0", :pending, "12345678") # amount coerced to 50.0
|
|
282
|
-
BankTransfer.new(75.25, :completed, "ABCD1234") # amount already a float
|
|
283
|
-
|
|
284
|
-
# These will raise ArgumentError:
|
|
285
|
-
BankTransfer.new(-10, :pending, "12345678") # amount must be positive
|
|
286
|
-
BankTransfer.new(100, :invalid, "12345678") # invalid status
|
|
287
|
-
BankTransfer.new(100, :pending, "123") # invalid reference number
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
Validations are run in the order they're defined, after any coercions. This lets you build up complex validation rules
|
|
291
|
-
while keeping them readable and maintainable.
|
|
292
|
-
|
|
293
|
-
### Visibility Control
|
|
294
|
-
|
|
295
|
-
Control access to your attributes:
|
|
296
|
-
|
|
297
|
-
```ruby
|
|
298
|
-
class SecretAgent
|
|
299
|
-
include Domainic::Attributer
|
|
300
|
-
|
|
301
|
-
argument :code_name
|
|
302
|
-
option :real_name do
|
|
303
|
-
private_read # Can't read real_name from outside
|
|
304
|
-
private_write # Can't write real_name from outside
|
|
305
|
-
end
|
|
306
|
-
option :mission do
|
|
307
|
-
protected # Both read and write are protected
|
|
308
|
-
end
|
|
309
|
-
end
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
### Change Callbacks
|
|
313
|
-
|
|
314
|
-
React to attribute changes:
|
|
315
|
-
|
|
316
|
-
```ruby
|
|
317
|
-
class Thermostat
|
|
318
|
-
include Domainic::Attributer
|
|
319
|
-
|
|
320
|
-
option :temperature do
|
|
321
|
-
default 20
|
|
322
|
-
on_change ->(old_val, new_val) {
|
|
323
|
-
puts "Temperature changing from #{old_val}°C to #{new_val}°C"
|
|
324
|
-
}
|
|
325
|
-
end
|
|
326
|
-
end
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
### Default Values
|
|
330
|
-
|
|
331
|
-
Provide static defaults or generate them dynamically:
|
|
332
|
-
|
|
333
|
-
```ruby
|
|
334
|
-
class Order
|
|
335
|
-
include Domainic::Attributer
|
|
336
|
-
|
|
337
|
-
argument :items
|
|
338
|
-
option :created_at do
|
|
339
|
-
default { Time.now } # Dynamic default
|
|
340
|
-
end
|
|
341
|
-
option :status do
|
|
342
|
-
default "pending" # Static default
|
|
343
|
-
end
|
|
344
|
-
end
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
### Custom Method Names
|
|
51
|
+
## Installation
|
|
348
52
|
|
|
349
|
-
|
|
53
|
+
Add this line to your application's Gemfile:
|
|
350
54
|
|
|
351
55
|
```ruby
|
|
352
|
-
|
|
353
|
-
include Domainic.Attributer(argument: :param, option: :setting)
|
|
354
|
-
|
|
355
|
-
param :environment
|
|
356
|
-
setting :debug_mode, default: false
|
|
357
|
-
end
|
|
56
|
+
gem 'domainic-attributer'
|
|
358
57
|
```
|
|
359
58
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
```ruby
|
|
363
|
-
class Configuration
|
|
364
|
-
include Domainic.Attributer(argument: nil)
|
|
59
|
+
Or install it yourself as:
|
|
365
60
|
|
|
366
|
-
|
|
367
|
-
|
|
61
|
+
```bash
|
|
62
|
+
gem install domainic-attributer
|
|
368
63
|
```
|
|
369
64
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
Convert your objects to hashes easily:
|
|
65
|
+
## Documentation
|
|
373
66
|
|
|
374
|
-
|
|
375
|
-
class Product
|
|
376
|
-
include Domainic::Attributer
|
|
67
|
+
For detailed usage instructions and examples, see [USAGE.md](./docs/USAGE.md).
|
|
377
68
|
|
|
378
|
-
|
|
379
|
-
argument :price
|
|
380
|
-
option :description, default: ""
|
|
381
|
-
option :internal_id do
|
|
382
|
-
private # Won't be included in to_h output
|
|
383
|
-
end
|
|
384
|
-
end
|
|
69
|
+
## Contributing
|
|
385
70
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
```
|
|
71
|
+
We welcome contributions! Please see our
|
|
72
|
+
[Contributing Guidelines](https://github.com/domainic/domainic/wiki/CONTRIBUTING) for:
|
|
389
73
|
|
|
390
|
-
|
|
74
|
+
* Development setup and workflow
|
|
75
|
+
* Code style and documentation standards
|
|
76
|
+
* Testing requirements
|
|
77
|
+
* Pull request process
|
|
391
78
|
|
|
392
|
-
|
|
79
|
+
Before contributing, please review our [Code of Conduct](https://github.com/domainic/domainic/wiki/CODE_OF_CONDUCT).
|
|
393
80
|
|
|
394
81
|
## License
|
|
395
82
|
|
|
396
|
-
The gem is available as open source under the terms of the [MIT License](LICENSE).
|
|
83
|
+
The gem is available as open source under the terms of the [MIT License](./LICENSE).
|