activerecord-exclusive-arc 0.1.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -5
- data/lib/exclusive_arc/model.rb +30 -17
- data/lib/exclusive_arc/version.rb +1 -1
- data/lib/generators/exclusive_arc_generator.rb +1 -1
- metadata +1 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27e01ec54aa223f1e36904771298125b451731632cca44ae6d0d15627cbcf879
|
4
|
+
data.tar.gz: 97990f81b596836909e67609a2d9745d6be13f0852373829656d2218454f6029
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 448c3910176f2f9163d0cfac054482fa2c6dc96b3e67d1093668626e2dbc94cfdeb59adcc371f3890af35541f9e4db7b8f4db0cd0108db09cd6bfe68de4954be
|
7
|
+
data.tar.gz: ec36d41ce0896b6505f76eb5112dd999db1cb334d9d0b956d82d7f043efba1e4999ef32ddbf0a384c140b5dcba01dfbaf7606b4638ac94381fbc8408751a7d3a
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ fact that the Ruby class name is stored in the database as a string. If you want
|
|
10
10
|
Ruby class used for such reasons, you must also update the database strings that represent it. The bleeding
|
11
11
|
of application-layer definitions into the database may become a liability.
|
12
12
|
|
13
|
-
Another common argument concerns referential integrity.
|
13
|
+
Another common argument concerns referential integrity. _Foreign Key Constraints_ are a common mechanism to
|
14
14
|
ensure primary keys of tables can be reliably used as foreign keys on others. This becomes harder to enforce
|
15
15
|
when a column that represents a Ruby class is one of the components required for unique identification.
|
16
16
|
|
@@ -19,8 +19,8 @@ polymorphic: true` relationship and the fact that polymorphic indexes require mu
|
|
19
19
|
|
20
20
|
### So how does this work?
|
21
21
|
|
22
|
-
It reduces the boilerplate of managing a
|
23
|
-
|
22
|
+
It reduces the boilerplate of managing a _Polymorphic Assication_ modeled as a pattern called an _Exclusive
|
23
|
+
Arc_. This maps nicely to a database constraint, a set of optional `belongs_to` relationships, some
|
24
24
|
polymorphic methods, and an `ActiveRecord` validation for good measure.
|
25
25
|
|
26
26
|
## How to use
|
@@ -49,7 +49,7 @@ This will inject code into your `Comment` Model:
|
|
49
49
|
```ruby
|
50
50
|
class Comment < ApplicationRecord
|
51
51
|
include ExclusiveArc::Model
|
52
|
-
|
52
|
+
has_exclusive_arc :commentable, [:post, :comment]
|
53
53
|
end
|
54
54
|
```
|
55
55
|
|
@@ -73,6 +73,17 @@ end
|
|
73
73
|
|
74
74
|
It's a bit more involved than that, but it demonstrates the essense of the API as an `ActiveRecord` user.
|
75
75
|
|
76
|
+
If you need to customize a specific `belongs_to` relationship, you can do so by declaring it before
|
77
|
+
`has_exclusive_arc`:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
class Comment < ApplicationRecord
|
81
|
+
include ExclusiveArc::Model
|
82
|
+
belongs_to :post, -> { where(comments_enabled: true) }, optional: true
|
83
|
+
has_exclusive_arc :commentable, [:post, :comment]
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
76
87
|
Continuing with our example, the generator command would also produce a migration that looks like this:
|
77
88
|
|
78
89
|
```ruby
|
@@ -135,4 +146,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/waymon
|
|
135
146
|
### License
|
136
147
|
|
137
148
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
138
|
-
|
data/lib/exclusive_arc/model.rb
CHANGED
@@ -8,27 +8,39 @@ module ExclusiveArc
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class_methods do
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
exclusive_arcs[name] = Definition.new(
|
17
|
-
reflections: reflections.slice(*belong_tos.map(&:to_s)),
|
18
|
-
options: options
|
19
|
-
)
|
11
|
+
def has_exclusive_arc(*args)
|
12
|
+
arc = args[0]
|
13
|
+
belong_tos = args[1]
|
14
|
+
belong_tos.map do |option|
|
15
|
+
next if reflections[option.to_s]
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
belongs_to(option, optional: true)
|
18
|
+
end
|
19
|
+
exclusive_arcs[arc] = Definition.new(
|
20
|
+
reflections: reflections.slice(*belong_tos.map(&:to_s)),
|
21
|
+
options: args[2] || {}
|
22
|
+
)
|
25
23
|
|
26
|
-
|
27
|
-
|
24
|
+
belong_tos.each do |option|
|
25
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
26
|
+
def #{option}=(polymorphic)
|
27
|
+
@#{arc} = nil unless @#{arc} == polymorphic
|
28
|
+
super
|
28
29
|
end
|
29
30
|
RUBY
|
30
31
|
end
|
31
32
|
|
33
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
34
|
+
def #{arc}
|
35
|
+
@#{arc} ||= (#{belong_tos.join(" || ")})
|
36
|
+
end
|
37
|
+
|
38
|
+
def #{arc}=(polymorphic)
|
39
|
+
assign_exclusive_arc(:#{arc}, polymorphic)
|
40
|
+
@#{arc} = polymorphic
|
41
|
+
end
|
42
|
+
RUBY
|
43
|
+
|
32
44
|
validate :validate_exclusive_arcs
|
33
45
|
end
|
34
46
|
end
|
@@ -36,9 +48,10 @@ module ExclusiveArc
|
|
36
48
|
private
|
37
49
|
|
38
50
|
def assign_exclusive_arc(arc, polymorphic)
|
39
|
-
exclusive_arcs.fetch(arc).reflections.
|
40
|
-
|
51
|
+
attributes = exclusive_arcs.fetch(arc).reflections.to_h do |name, reflection|
|
52
|
+
[name, polymorphic.is_a?(reflection.klass) ? polymorphic : nil]
|
41
53
|
end
|
54
|
+
assign_attributes attributes
|
42
55
|
end
|
43
56
|
|
44
57
|
def validate_exclusive_arcs
|
@@ -32,7 +32,7 @@ class ExclusiveArcGenerator < ActiveRecord::Generators::Base
|
|
32
32
|
class_name.demodulize,
|
33
33
|
<<~RB
|
34
34
|
#{indents}include ExclusiveArc::Model
|
35
|
-
#{indents}
|
35
|
+
#{indents}has_exclusive_arc #{model_exclusive_arcs}
|
36
36
|
RB
|
37
37
|
)
|
38
38
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-exclusive-arc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- justin talbott
|
@@ -50,26 +50,6 @@ dependencies:
|
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '8'
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: railties
|
55
|
-
requirement: !ruby/object:Gem::Requirement
|
56
|
-
requirements:
|
57
|
-
- - ">="
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: '6.1'
|
60
|
-
- - "<"
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: '8'
|
63
|
-
type: :runtime
|
64
|
-
prerelease: false
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - ">="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '6.1'
|
70
|
-
- - "<"
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
version: '8'
|
73
53
|
description:
|
74
54
|
email:
|
75
55
|
- gmail@justintalbott.com
|