active_module 0.1.6 → 0.1.8
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/README.md +77 -37
- data/lib/active_module/comparison.rb +3 -3
- data/lib/active_module/module_refinement.rb +4 -0
- data/lib/active_module/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b80aaae788c312746df8dcaba68bfda8f881fc2c22d7642b509546bdab198bc0
|
4
|
+
data.tar.gz: 84674ab108e9b639327f7531f678a12b8dbf31ab25c01088f8839458b71d1cac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a89843336735a230e13691069fd3a2e919403a140712476bb5176862fd0bb72df6ff069fa9d3ca9635c2dadc1a602863122a2ec384f8414754a560da02561698
|
7
|
+
data.tar.gz: f7b03c281aafba2a1bf187f7ed9b049c9dd3798bafdf411c3710964e2cbc087dedd72937c897925bdcbb9f4887e625f5d893b69640df853f738324b12b955e7d
|
data/README.md
CHANGED
@@ -1,19 +1,21 @@
|
|
1
|
-
# ActiveModule
|
2
1
|
|
3
|
-
|
2
|
+
# active_module
|
3
|
+

|
4
|
+
|
5
|
+
#### *Modules and Classes as first-class active record values!*
|
4
6
|
|
5
7
|
ActiveModel/ActiveRecord implementation of the Module attribute type.
|
6
8
|
|
7
|
-
- Allows storing a reference to a `Module` or `Class`
|
8
|
-
|
9
|
-
-
|
10
|
-
-
|
9
|
+
- Allows storing a reference to a `Module` or `Class` in a `:string` database field
|
10
|
+
- Automatically casts strings and symbols into modules when creating and querying objects
|
11
|
+
- Symbols or strings refer to the modules using unqualified names
|
12
|
+
- It is safe and efficient
|
11
13
|
|
12
14
|
This is a very generic mechanism that enables many possible utilizations, for instance:
|
13
|
-
-
|
14
|
-
- Rapid prototyping static domain objects
|
15
|
-
- Static configuration management
|
16
|
-
- Rich Java/C#-like enums
|
15
|
+
- **Composition-based polymorphism (Strategy design pattern)**
|
16
|
+
- **Rapid prototyping static domain objects**
|
17
|
+
- **Static configuration management**
|
18
|
+
- **Rich Java/C#-like enums**
|
17
19
|
|
18
20
|
You can find examples of these in [Usage -> Examples :](#Examples)
|
19
21
|
|
@@ -36,8 +38,19 @@ object.module_field = "Module"
|
|
36
38
|
object.module_field #=> Nested::Module:Module
|
37
39
|
```
|
38
40
|
|
39
|
-
|
41
|
+
Query them like this:
|
42
|
+
```ruby
|
43
|
+
MyARObject.where(module_field: Nested::Module)
|
44
|
+
MyARObject.where(module_field: :Module)
|
45
|
+
MyARObject.where(module_field: "Module")
|
46
|
+
object.module_field #=> Nested::Module:Module
|
47
|
+
```
|
48
|
+
|
49
|
+
And compare them like this:
|
50
|
+
|
40
51
|
```ruby
|
52
|
+
object.module_field == Nested::Module
|
53
|
+
|
41
54
|
module MyNameSpace
|
42
55
|
using ActiveModule::Comparison
|
43
56
|
|
@@ -51,7 +64,7 @@ end
|
|
51
64
|
Add to your gemfile - and if you are using rails - that's all you need:
|
52
65
|
|
53
66
|
```ruby
|
54
|
-
gem 'active_module', "~>0.1"
|
67
|
+
gem 'active_module', "~> 0.1"
|
55
68
|
```
|
56
69
|
|
57
70
|
If you are not using rails, just issue this command after loading active record
|
@@ -77,7 +90,7 @@ create_table :my_ar_objects do |t|
|
|
77
90
|
end
|
78
91
|
```
|
79
92
|
|
80
|
-
Now given this module
|
93
|
+
Now given this random module hierarchy:
|
81
94
|
```ruby
|
82
95
|
class MyARObject < ActiveRecord::Base
|
83
96
|
module MyModule1; end
|
@@ -154,13 +167,44 @@ module YourClassOrModuleThatWantsToCompare
|
|
154
167
|
end
|
155
168
|
```
|
156
169
|
|
170
|
+
or like this, if you don't want to use the refinement:
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
ActiveModule::Comparison.compare(my_ar_object.module_field, :MyModule1)
|
174
|
+
```
|
175
|
+
|
176
|
+
but in this last case it would probably make more sense to simply use a module literal:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
my_ar_object.module_field == MyClass::MyModule1
|
180
|
+
```
|
181
|
+
|
182
|
+
|
157
183
|
## Examples
|
158
184
|
|
159
|
-
###
|
185
|
+
### Composition-based polymorphism (Strategy design pattern)
|
160
186
|
|
161
187
|
[The Strategy design pattern](https://en.wikipedia.org/wiki/Strategy_pattern) allows composition based polymorphism. This enables runtime polymorphism (by changing the strategy in runtime),
|
162
188
|
and multiple-polymorphism (by composing an object of multiple strategies).
|
163
189
|
|
190
|
+
If you want to use classes this will do:
|
191
|
+
```ruby
|
192
|
+
class MyARObject < ActiveRecord::Base
|
193
|
+
attribute :strategy_class, :active_module, possible_modules: StrategySuperclass.subclasses
|
194
|
+
|
195
|
+
def strategy
|
196
|
+
@strategy ||= strategy_class.new(some_args_from_the_instance)
|
197
|
+
end
|
198
|
+
|
199
|
+
def run_strategy!(args)
|
200
|
+
strategy.call(args)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
```
|
204
|
+
|
205
|
+
But if you are not in the mood to define a class hierarchy for it (or if you are performance-savy),
|
206
|
+
you may use modules instead:
|
207
|
+
|
164
208
|
```ruby
|
165
209
|
class MyARObject < ActiveRecord::Base
|
166
210
|
module Strategy1
|
@@ -179,16 +223,13 @@ class MyARObject < ActiveRecord::Base
|
|
179
223
|
:active_module,
|
180
224
|
possible_modules: [Strategy1, Strategy2]
|
181
225
|
|
182
|
-
def run_strategy!
|
183
|
-
|
184
|
-
# in this case strategies were classes we could also
|
185
|
-
# instantiate them
|
186
|
-
strategy.call
|
226
|
+
def run_strategy!(some_args)
|
227
|
+
strategy.call(some_args, other_args)
|
187
228
|
end
|
188
229
|
end
|
189
230
|
|
190
231
|
MyARObject.create!(module_field: :Strategy1).run_strategy! #=> "strategy1 called"
|
191
|
-
MyARObject.create!(module_field: :
|
232
|
+
MyARObject.create!(module_field: :Strategy2).run_strategy! #=> "strategy2 called"
|
192
233
|
```
|
193
234
|
|
194
235
|
|
@@ -250,6 +291,10 @@ this is how you could do so:
|
|
250
291
|
# Provider domain Object
|
251
292
|
module Provider
|
252
293
|
# As if the domain model class
|
294
|
+
def self.all
|
295
|
+
[Ebay, Amazon]
|
296
|
+
end
|
297
|
+
|
253
298
|
module Base
|
254
299
|
def do_something!
|
255
300
|
"do something with #{something_from_an_instance}"
|
@@ -274,11 +319,6 @@ module Provider
|
|
274
319
|
"the amazon provider config"
|
275
320
|
end
|
276
321
|
end
|
277
|
-
|
278
|
-
# As if the domain model class
|
279
|
-
def self.all
|
280
|
-
[Ebay, Amazon]
|
281
|
-
end
|
282
322
|
end
|
283
323
|
```
|
284
324
|
|
@@ -345,6 +385,18 @@ Java/C# enums allow defining methods on the enum, which are shared across all en
|
|
345
385
|
|
346
386
|
```ruby
|
347
387
|
module PipelineStage
|
388
|
+
module_function
|
389
|
+
|
390
|
+
def all
|
391
|
+
[InitialContact, InNegotiations, LostDeal, PaidOut]
|
392
|
+
end
|
393
|
+
|
394
|
+
def cast(stage)
|
395
|
+
self.all.map(&:external_provider_code).find{|code| code == stage} ||
|
396
|
+
self.all.map(&:database_representation).find{|code| code == stage} ||
|
397
|
+
self.all.map(&:frontend_representation).find{|code| code == stage}
|
398
|
+
end
|
399
|
+
|
348
400
|
module Base
|
349
401
|
def external_provider_code
|
350
402
|
@external_provider_code ||= self.name.underscore
|
@@ -374,18 +426,6 @@ module PipelineStage
|
|
374
426
|
module PaidOut
|
375
427
|
extend Base
|
376
428
|
end
|
377
|
-
|
378
|
-
module_function
|
379
|
-
|
380
|
-
def all
|
381
|
-
[InitialContact, InNegotiations, LostDeal, PaidOut]
|
382
|
-
end
|
383
|
-
|
384
|
-
def cast(stage)
|
385
|
-
self.all.map(&:external_provider_code).find{|code| code == stage} ||
|
386
|
-
self.all.map(&:database_representation).find{|code| code == stage} ||
|
387
|
-
self.all.map(&:frontend_representation).find{|code| code == stage}
|
388
|
-
end
|
389
429
|
end
|
390
430
|
|
391
431
|
class MyARObject < ActiveRecord::Base
|
@@ -7,10 +7,10 @@ module ActiveModule
|
|
7
7
|
|
8
8
|
def =~(other)
|
9
9
|
case other
|
10
|
-
when ::String
|
11
|
-
(@possible_names ||= possible_names).include?(other)
|
12
10
|
when ::Symbol
|
13
|
-
|
11
|
+
possible_symbol_names_set.include?(other)
|
12
|
+
when ::String
|
13
|
+
possible_symbol_names_set.include?(other.to_sym)
|
14
14
|
else
|
15
15
|
self == other
|
16
16
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_module
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Rolo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '9'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '7'
|
22
|
+
version: '7.1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: '9'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '7'
|
32
|
+
version: '7.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: bundler
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 1.15.0
|
47
|
-
description:
|
47
|
+
description: ActiveModel/ActiveRecord module attribute type implementation
|
48
48
|
email:
|
49
49
|
- pedrorolo@gmail.com
|
50
50
|
executables: []
|
@@ -89,5 +89,5 @@ requirements: []
|
|
89
89
|
rubygems_version: 3.5.7
|
90
90
|
signing_key:
|
91
91
|
specification_version: 4
|
92
|
-
summary:
|
92
|
+
summary: Modules and Classes as first-class active record values
|
93
93
|
test_files: []
|