discriminable 2.1.1 → 2.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 +7 -0
- data/README.md +21 -5
- data/Rakefile +5 -0
- data/TODO.md +5 -4
- data/lib/discriminable/version.rb +1 -1
- data/lib/discriminable.rb +31 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63543cd5b47a63a6870368d2d16c9570e7cd0cebb53cfd296d717884c37fb4c3
|
4
|
+
data.tar.gz: b4417f8e33ff2d24a71a9ec436a26b66c38cab59395ed7fbb1182c818ff48439
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e053310353bf54fcfbef35b32b5de0015f9b28903cb6dc04631bc04cfbaeec274359c0dc34d687eca7a9813eee36590f2c745e90d3c9587e381fceb9bb38886d
|
7
|
+
data.tar.gz: dbf905a1c5a7c7c10154ad5cc9eb73b67d81cd65513e5ac7a1ab33086dbfaee92a885b511942ecc37db4b8528a75283d270ec807db9c4982defb7ba7f2c814a8
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [2.2.0](https://github.com/gregorw/discriminable/compare/v2.1.1...v2.2.0) (2022-04-16)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* Alternative syntax respecting open-closed principle ([8a8f885](https://github.com/gregorw/discriminable/commit/8a8f8857dc24753dc08f21b2bfbb7b4317b7ed5c))
|
9
|
+
|
3
10
|
### [2.1.1](https://github.com/gregorw/discriminable/compare/v2.1.0...v2.1.1) (2022-04-15)
|
4
11
|
|
5
12
|
|
data/README.md
CHANGED
@@ -29,20 +29,36 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
29
29
|
## Usage
|
30
30
|
|
31
31
|
```ruby
|
32
|
-
ActiveRecord::
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
class Order < ActiveRecord::Base
|
33
|
+
include Discriminable
|
34
|
+
|
35
|
+
enum state: { open: 0, completed: 1 }
|
36
|
+
discriminable state: { open: "Cart" }
|
36
37
|
end
|
37
38
|
|
39
|
+
class Cart < Order
|
40
|
+
end
|
41
|
+
|
42
|
+
Cart.create
|
43
|
+
=> #<Cart id: 1, state: "open">
|
44
|
+
Order.all
|
45
|
+
=> #<ActiveRecord::Relation [#<Cart id: 1, state: "open">]>
|
46
|
+
```
|
47
|
+
|
48
|
+
### Alternative syntax
|
49
|
+
|
50
|
+
Instead of defining subclass names within the parent you may prefer to be open for extension but closed for modification (open-closed principle) using the alternative syntax.
|
51
|
+
|
52
|
+
```ruby
|
38
53
|
class Order < ActiveRecord::Base
|
39
54
|
include Discriminable
|
40
55
|
|
41
56
|
enum state: { open: 0, completed: 1 }
|
42
|
-
|
57
|
+
discriminable_by :state
|
43
58
|
end
|
44
59
|
|
45
60
|
class Cart < Order
|
61
|
+
discriminable_as :open
|
46
62
|
end
|
47
63
|
|
48
64
|
Cart.create
|
data/Rakefile
CHANGED
data/TODO.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
- [
|
2
|
-
- [
|
3
|
-
- [
|
1
|
+
- [x] multiple values per subclass
|
2
|
+
- [x] default to first value when using hash syntax
|
3
|
+
- [x] open-closed principle
|
4
|
+
- [ ] use `type` column with enum, int, string, etc.
|
4
5
|
- [ ] test permitted attributes
|
5
|
-
- [ ] `self.abstract_class = true`
|
6
|
+
- [ ] `self.abstract_class = true`
|
data/lib/discriminable.rb
CHANGED
@@ -26,6 +26,8 @@ module Discriminable
|
|
26
26
|
included do
|
27
27
|
class_attribute :discriminable_map, instance_writer: false
|
28
28
|
class_attribute :discriminable_inverse_map, instance_writer: false
|
29
|
+
class_attribute :discriminable_values, instance_writer: false
|
30
|
+
class_attribute :discriminable_as_descendant_value, instance_writer: false
|
29
31
|
end
|
30
32
|
|
31
33
|
# Specify the column to use for discrimination.
|
@@ -33,7 +35,7 @@ module Discriminable
|
|
33
35
|
def discriminable(**options)
|
34
36
|
raise "Subclasses should not override .discriminable" unless base_class?
|
35
37
|
|
36
|
-
|
38
|
+
attribute, map = options.first
|
37
39
|
|
38
40
|
self.discriminable_map = map.with_indifferent_access
|
39
41
|
|
@@ -41,14 +43,41 @@ module Discriminable
|
|
41
43
|
# { a: "C", b: "C" }.invert => { "C" => :b }
|
42
44
|
# { a: "C", b: "C" }.to_a.reverse.to_h.invert => { "C" => :a }
|
43
45
|
self.discriminable_inverse_map = map.to_a.reverse.to_h.invert
|
44
|
-
self.inheritance_column =
|
46
|
+
self.inheritance_column = attribute.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
def discriminable_by(attribute)
|
50
|
+
raise "Subclasses should not override .discriminable_by" unless base_class?
|
51
|
+
|
52
|
+
self.discriminable_as_descendant_value = true
|
53
|
+
self.inheritance_column = attribute.to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
def discriminable_as(*values)
|
57
|
+
raise "Only subclasses should specify .discriminable_as" if base_class?
|
58
|
+
|
59
|
+
self.discriminable_values = values.map do |value|
|
60
|
+
value.instance_of?(Symbol) ? value.to_s : value
|
61
|
+
end
|
45
62
|
end
|
46
63
|
|
47
64
|
def sti_name
|
65
|
+
if discriminable_as_descendant_value
|
66
|
+
self.discriminable_inverse_map ||= Hash.new do |map, value|
|
67
|
+
map[value] = name.constantize.discriminable_values&.first
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
48
71
|
discriminable_inverse_map[name]
|
49
72
|
end
|
50
73
|
|
51
74
|
def sti_class_for(value)
|
75
|
+
if discriminable_as_descendant_value
|
76
|
+
self.discriminable_map ||= Hash.new do |map, v|
|
77
|
+
map[v] = descendants.detect { |d| d.discriminable_values.include? v }&.name
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
52
81
|
return self unless (type_name = discriminable_map[value])
|
53
82
|
|
54
83
|
super type_name
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: discriminable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregor Wassmann
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04-
|
11
|
+
date: 2022-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|