active-triples 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +8 -9
- data/CHANGES.md +69 -0
- data/Gemfile +0 -2
- data/Guardfile +1 -2
- data/active-triples.gemspec +3 -3
- data/lib/active/triples.rb +1 -0
- data/lib/active_triples.rb +4 -0
- data/lib/active_triples/configurable.rb +3 -1
- data/lib/active_triples/configuration.rb +1 -0
- data/lib/active_triples/configuration/item.rb +1 -0
- data/lib/active_triples/configuration/item_factory.rb +1 -0
- data/lib/active_triples/configuration/merge_item.rb +5 -2
- data/lib/active_triples/extension_strategy.rb +1 -0
- data/lib/active_triples/identifiable.rb +1 -0
- data/lib/active_triples/list.rb +2 -0
- data/lib/active_triples/nested_attributes.rb +1 -1
- data/lib/active_triples/node_config.rb +5 -3
- data/lib/active_triples/persistable.rb +1 -0
- data/lib/active_triples/persistence_strategies/parent_strategy.rb +104 -29
- data/lib/active_triples/persistence_strategies/persistence_strategy.rb +15 -7
- data/lib/active_triples/persistence_strategies/repository_strategy.rb +26 -22
- data/lib/active_triples/properties.rb +84 -6
- data/lib/active_triples/property.rb +35 -4
- data/lib/active_triples/property_builder.rb +38 -4
- data/lib/active_triples/rdf_source.rb +225 -75
- data/lib/active_triples/reflection.rb +42 -3
- data/lib/active_triples/relation.rb +330 -73
- data/lib/active_triples/repositories.rb +4 -2
- data/lib/active_triples/resource.rb +1 -0
- data/lib/active_triples/schema.rb +1 -0
- data/lib/active_triples/undefined_property_error.rb +27 -0
- data/lib/active_triples/version.rb +2 -1
- data/spec/active_triples/configurable_spec.rb +3 -2
- data/spec/active_triples/configuration_spec.rb +2 -1
- data/spec/active_triples/extension_strategy_spec.rb +2 -1
- data/spec/active_triples/identifiable_spec.rb +7 -11
- data/spec/active_triples/list_spec.rb +1 -4
- data/spec/active_triples/nested_attributes_spec.rb +4 -3
- data/spec/active_triples/persistable_spec.rb +4 -1
- data/spec/active_triples/persistence_strategies/parent_strategy_spec.rb +141 -11
- data/spec/active_triples/persistence_strategies/persistence_strategy_spec.rb +1 -0
- data/spec/active_triples/persistence_strategies/repository_strategy_spec.rb +32 -17
- data/spec/active_triples/properties_spec.rb +68 -33
- data/spec/active_triples/property_builder_spec.rb +36 -0
- data/spec/active_triples/property_spec.rb +15 -1
- data/spec/active_triples/rdf_source_spec.rb +544 -6
- data/spec/active_triples/reflection_spec.rb +78 -0
- data/spec/active_triples/relation_spec.rb +505 -3
- data/spec/active_triples/repositories_spec.rb +3 -1
- data/spec/active_triples/resource_spec.rb +90 -147
- data/spec/active_triples/schema_spec.rb +3 -2
- data/spec/active_triples_spec.rb +1 -0
- data/spec/integration/dummies/dummy_resource_a.rb +6 -0
- data/spec/integration/dummies/dummy_resource_b.rb +6 -0
- data/spec/integration/parent_persistence_spec.rb +18 -0
- data/spec/integration/reciprocal_properties_spec.rb +69 -0
- data/spec/pragmatic_context_spec.rb +10 -8
- data/spec/spec_helper.rb +5 -0
- data/spec/support/active_model_lint.rb +4 -6
- data/spec/support/dummies/basic_persistable.rb +2 -11
- data/spec/support/matchers.rb +11 -0
- data/spec/support/shared_examples/persistence_strategy.rb +3 -16
- metadata +20 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1f422e5ac96c89ebdaeeb9d97d52ae3d5bfe526
|
4
|
+
data.tar.gz: b5fd9203d247be04fccab63466eee59bcc9af078
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26f27fa5aae3444a211f339c2dcb5dcf26950b31f6f98697b09977f233fe0e23049a245f2ba1b3262b6104caf27b37e254ea5c829fc30f2daea675250ed4988a
|
7
|
+
data.tar.gz: 22400ed6fd5ace6f4772ca8b1c0ddb5a98e99be0d38fdeac42a8bce900d7cf65226e44c399fd38e1174770d1f040a0a98b4bd0589751fa27194443fa17591c3d
|
data/.travis.yml
CHANGED
@@ -4,14 +4,13 @@ script: "bundle exec rspec spec"
|
|
4
4
|
sudo: false
|
5
5
|
cache: bundler
|
6
6
|
rvm:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
- rbx-2
|
7
|
+
- 2.0
|
8
|
+
- 2.1
|
9
|
+
- 2.2.4
|
10
|
+
- 2.3.0
|
11
|
+
- jruby-9.0.4.0
|
12
|
+
- rbx-2
|
14
13
|
matrix:
|
15
14
|
allow_failures:
|
16
|
-
- rvm: jruby
|
17
|
-
- rvm:
|
15
|
+
- rvm: jruby-9.0.4.0
|
16
|
+
- rvm: rbx-2
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,72 @@
|
|
1
|
+
0.8.2
|
2
|
+
-----
|
3
|
+
* Allow PersistenceStrategy set by property config [Tom Johnson]
|
4
|
+
* Extend NodeConfig for arbitrary properties [Tom Johnson]
|
5
|
+
* Add `Relation#delete?` and `#swap` [Tom Johnson]
|
6
|
+
* Make Relation#delete singular; add #subtract [Tom Johnson]
|
7
|
+
* Re-add `Relation#delete` with a new implementation [Tom Johnson]
|
8
|
+
* Documentation and formatting cleanup on Relation [Tom Johnson]
|
9
|
+
* Remove Relation#reset! [Tom Johnson]
|
10
|
+
* Remove `Relation#[]=` [Tom Johnson]
|
11
|
+
* Remove Relation#delete [Tom Johnson]
|
12
|
+
* FIX #200 Use == instead of eql? for resource equality test [E. Lynette Rayle]
|
13
|
+
* Add some docs and tests for `PropertyBuilder` [Tom Johnson]
|
14
|
+
* Test undefined property on Relation#set [Tom Johnson]
|
15
|
+
* add loaded flag to lazy load property sources with parent_strategy [E. Lynette Rayle]
|
16
|
+
* Add deprecation warning [MJ Suhonos]
|
17
|
+
* Rename #obj to #source for clarity [MJ Suhonos]
|
18
|
+
* Update Guardfile [MJ Suhonos]
|
19
|
+
* Update comment terminology [MJ Suhonos]
|
20
|
+
* Remove reference to concrete persistable from abstract class [MJ Suhonos]
|
21
|
+
* Allow fetch to pass args to RDF::Reader.open [Justin Coyne]
|
22
|
+
* Delegate join to Relation. [Trey Terrell]
|
23
|
+
* Change ParentStrategy usage [Tom Johnson]
|
24
|
+
* Delegate #size in Relation. [Trey Terrell]
|
25
|
+
* Remove singleton_class call from RepositoryStrategy [Tom Johnson]
|
26
|
+
* Convert ancestors enumerator method to Class [Tom Johnson]
|
27
|
+
* Avoid circularity in `ParentStrategy` [Tom Johnson]
|
28
|
+
* Update .travis.yml Rubies to match RDF.rb [Tom Johnson]
|
29
|
+
* Add frozen_string_literals pragma [Justin Coyne]
|
30
|
+
* Fixup specs [Tom Johnson]
|
31
|
+
* Specs/docs for ValueError scenarios on #set_value [Tom Johnson]
|
32
|
+
* Add initial docs/specs for `RDFSource#attributes` [Tom Johnson]
|
33
|
+
* Add docs and specs for `Relation#first_or_create` [Tom Johnson]
|
34
|
+
* Add tests & docs for `Relation#build` [Tom Johnson]
|
35
|
+
* Make `Relation#clear` atomic [Tom Johnson]
|
36
|
+
* Test `RDFSource#rdf_label` [Tom Johnson]
|
37
|
+
* Fix for circular parent relationships [Tom Johnson]
|
38
|
+
* Add documentation and tests for key Relation [Tom Johnson]
|
39
|
+
* Refactor Relation#value_arguments [Tom Johnson]
|
40
|
+
* Move property methods from RDFSource in Properties [Tom Johnson]
|
41
|
+
* Add documentation and some tests for Properties [Tom Johnson]
|
42
|
+
* Refactor and rearrange RDFSource & Reflection [Tom Johnson]
|
43
|
+
* Finish documentation and testing of Reflection [Tom Johnson]
|
44
|
+
* Cleaner handling of undefined properties [Tom Johnson]
|
45
|
+
* Add some tests for `#get_values` [Tom Johnson]
|
46
|
+
* Make `#set_value` return the Relation it updates [Tom Johnson]
|
47
|
+
* Add triple in `#set_value` when argument is self [Tom Johnson]
|
48
|
+
* Removes odd logic surrounding property clearance [Tom Johnson]
|
49
|
+
* Removing OpenStruct in favor of PORO [Jeremy Friesen]
|
50
|
+
* Switching from Array() to Array.wrap [Jeremy Friesen]
|
51
|
+
* Fixup RDF.rb and rdf-spec dependencies [Tom Johnson]
|
52
|
+
* Track latest `rdf-spec` and `rdf-vocab` [Tom Johnson]
|
53
|
+
* Complete update to use RDF::Vocab [Tom Johnson]
|
54
|
+
* Use rdf-vocab for vocabularies [Justin Coyne]
|
55
|
+
* Add `RDFSource#graph_name` since quads aren't returned [Tom Johnson]
|
56
|
+
* Update specs to use a managable invalid statement [Tom Johnson]
|
57
|
+
* Test with develop version of rdf-spec [Justin Coyne]
|
58
|
+
* Graph#query is faster than using Queryable#query [Justin Coyne]
|
59
|
+
* Update error handling specs. [Tom Johnson]
|
60
|
+
* Adds a default block to `RDFSource#fetch` [Tom Johnson]
|
61
|
+
* Run `ActiveModel` lints on `RDFSource` [Tom Johnson]
|
62
|
+
* Fix ActiveModel linter to test `#to_key` [Tom Johnson]
|
63
|
+
* Remove unnecessary lines in `parent_strategy_spec` [Tom Johnson]
|
64
|
+
* Make `Relation#predicate` a public method [Tom Johnson]
|
65
|
+
* Cleanup and unit tests for `RDFSource#get_value` [Tom Johnson]
|
66
|
+
* Test ActiveModel validations with RDF's `#valid?` [Tom Johnson]
|
67
|
+
* Children should not be persisted? unless their parents are. Fixes #148 [Justin Coyne]
|
68
|
+
|
69
|
+
|
1
70
|
0.8.1
|
2
71
|
-----
|
3
72
|
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# A sample Guardfile
|
2
2
|
# More info at https://github.com/guard/guard#readme
|
3
3
|
|
4
|
-
guard :rspec do
|
4
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
5
5
|
watch(%r{^spec/.+_spec\.rb$})
|
6
6
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
7
|
watch('spec/spec_helper.rb') { "spec" }
|
8
8
|
end
|
9
|
-
|
data/active-triples.gemspec
CHANGED
@@ -14,15 +14,15 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.license = "APACHE2"
|
15
15
|
s.required_ruby_version = '>= 1.9.3'
|
16
16
|
|
17
|
-
s.add_dependency('rdf', '
|
18
|
-
s.add_dependency('linkeddata', '~> 1.
|
17
|
+
s.add_dependency('rdf', '1.99')
|
18
|
+
s.add_dependency('linkeddata', '~> 1.99')
|
19
19
|
s.add_dependency('activemodel', '>= 3.0.0')
|
20
20
|
s.add_dependency('deprecation', '~> 0.1')
|
21
21
|
s.add_dependency('activesupport', '>= 3.0.0')
|
22
22
|
|
23
23
|
s.add_development_dependency('rdoc')
|
24
24
|
s.add_development_dependency('rspec')
|
25
|
-
s.add_development_dependency('rdf-spec')
|
25
|
+
s.add_development_dependency('rdf-spec', '~> 1.99')
|
26
26
|
s.add_development_dependency('coveralls')
|
27
27
|
s.add_development_dependency('guard-rspec')
|
28
28
|
s.add_development_dependency('webmock')
|
data/lib/active/triples.rb
CHANGED
data/lib/active_triples.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rdf'
|
2
3
|
require 'active_triples/version'
|
3
4
|
require 'active_support'
|
@@ -53,6 +54,9 @@ module ActiveTriples
|
|
53
54
|
'active_triples/persistence_strategies/parent_strategy'
|
54
55
|
autoload :RepositoryStrategy,
|
55
56
|
'active_triples/persistence_strategies/repository_strategy'
|
57
|
+
|
58
|
+
# error classes
|
59
|
+
autoload :UndefinedPropertyError
|
56
60
|
end
|
57
61
|
|
58
62
|
##
|
@@ -1,4 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'deprecation'
|
3
|
+
require 'active_support/core_ext/array/wrap'
|
2
4
|
|
3
5
|
module ActiveTriples
|
4
6
|
##
|
@@ -61,7 +63,7 @@ module ActiveTriples
|
|
61
63
|
end
|
62
64
|
|
63
65
|
def transform_type(values)
|
64
|
-
Array(values).map do |value|
|
66
|
+
Array.wrap(values).map do |value|
|
65
67
|
RDF::URI.new(value).tap do |uri|
|
66
68
|
RDFSource.type_registry[uri] = self
|
67
69
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_support/core_ext/array/wrap'
|
3
|
+
|
1
4
|
module ActiveTriples
|
2
5
|
class Configuration
|
3
6
|
# Configuration item which sets a value by turning the original into an array and
|
@@ -6,8 +9,8 @@ module ActiveTriples
|
|
6
9
|
# This enables multiple types to be set on an object, for example.
|
7
10
|
class MergeItem < Item
|
8
11
|
def set(value)
|
9
|
-
object.inner_hash[key] = Array(object.inner_hash[key])
|
10
|
-
object.inner_hash[key] |= Array(value)
|
12
|
+
object.inner_hash[key] = Array.wrap(object.inner_hash[key])
|
13
|
+
object.inner_hash[key] |= Array.wrap(value)
|
11
14
|
end
|
12
15
|
end
|
13
16
|
end
|
data/lib/active_triples/list.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveTriples
|
2
3
|
##
|
3
4
|
# An implementation of RDF::List intregrated with ActiveTriples.
|
@@ -162,6 +163,7 @@ module ActiveTriples
|
|
162
163
|
if subject == RDF.nil
|
163
164
|
@subject = RDF::Node.new
|
164
165
|
@graph = ListResource.new(subject)
|
166
|
+
@graph.list = self
|
165
167
|
@graph.type = RDF.List
|
166
168
|
end
|
167
169
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'active_support'
|
2
3
|
require 'active_support/concern'
|
3
4
|
require 'active_support/core_ext/class'
|
@@ -121,7 +122,6 @@ module ActiveTriples
|
|
121
122
|
assign_nested_attributes_for_collection_association(:#{association_name}, attributes)
|
122
123
|
## in lieu of autosave_association_callbacks just save all of em.
|
123
124
|
send(:#{association_name}).each {|obj| obj.marked_for_destruction? ? obj.destroy : nil}
|
124
|
-
send(:#{association_name}).reset!
|
125
125
|
end
|
126
126
|
eoruby
|
127
127
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveTriples
|
2
3
|
class NodeConfig
|
3
4
|
attr_accessor :predicate, :term, :class_name, :type, :behaviors, :cast
|
@@ -5,14 +6,15 @@ module ActiveTriples
|
|
5
6
|
def initialize(term, predicate, args={})
|
6
7
|
self.term = term
|
7
8
|
self.predicate = predicate
|
8
|
-
self.class_name = args.
|
9
|
-
self.cast = args.
|
9
|
+
self.class_name = args.delete(:class_name) { default_class_name }
|
10
|
+
self.cast = args.delete(:cast) { true }
|
11
|
+
@opts = args
|
10
12
|
yield(self) if block_given?
|
11
13
|
end
|
12
14
|
|
13
15
|
def [](value)
|
14
16
|
value = value.to_sym
|
15
|
-
self.respond_to?(value) ? self.send(value) :
|
17
|
+
self.respond_to?(value) ? self.send(value) : @opts[value]
|
16
18
|
end
|
17
19
|
|
18
20
|
def class_name
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveTriples
|
2
3
|
##
|
3
4
|
# Persistence strategy for projecting `RDFSource`s onto the graph of an owning
|
@@ -6,50 +7,76 @@ module ActiveTriples
|
|
6
7
|
class ParentStrategy
|
7
8
|
include PersistenceStrategy
|
8
9
|
|
9
|
-
# @!attribute [r]
|
10
|
+
# @!attribute [r] source
|
10
11
|
# the source to persist with this strategy
|
11
12
|
# @!attribute [r] parent
|
12
13
|
# the target parent source for persistence
|
13
|
-
attr_reader :
|
14
|
+
attr_reader :source, :parent
|
14
15
|
|
15
16
|
##
|
16
|
-
# @param
|
17
|
+
# @param source [RDFSource, RDF::Enumerable] the `RDFSource` (or other
|
17
18
|
# `RDF::Enumerable` to persist with the strategy.
|
18
|
-
def initialize(
|
19
|
-
@
|
19
|
+
def initialize(source)
|
20
|
+
@source = source
|
20
21
|
end
|
21
22
|
|
23
|
+
##
|
24
|
+
# Resources using this strategy are persisted only if their parent is also
|
25
|
+
# persisted.
|
26
|
+
#
|
27
|
+
# @see PersistenceStrategy#persisted?
|
28
|
+
def persisted?
|
29
|
+
super && parent.persisted?
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Indicates if the resource has been loaded from the repository (used for lazy load)
|
34
|
+
#
|
35
|
+
# @return [Boolean] true if loaded; else false.
|
36
|
+
def loaded?
|
37
|
+
@loaded ||= false
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Destroys the resource by removing it graph and references from the
|
42
|
+
# parent.
|
43
|
+
#
|
44
|
+
# @see PersistenceStrategy#destroy
|
22
45
|
def destroy
|
23
|
-
|
46
|
+
final_parent.delete(source.statements)
|
47
|
+
|
48
|
+
parent.statements.each do |statement|
|
49
|
+
parent.delete_statement(statement) if
|
50
|
+
statement.subject == source.rdf_subject ||
|
51
|
+
statement.object == source.rdf_subject
|
52
|
+
end
|
53
|
+
|
54
|
+
super { source.clear }
|
24
55
|
end
|
25
56
|
|
26
|
-
|
27
|
-
#
|
57
|
+
##
|
58
|
+
# @abstract Clear out any old assertions in the datastore / repository
|
59
|
+
# about this node or statement thus preparing to receive the updated
|
60
|
+
# assertions.
|
28
61
|
def erase_old_resource
|
29
|
-
|
30
|
-
final_parent.
|
31
|
-
|
32
|
-
statement.subject == obj.rdf_subject
|
33
|
-
end
|
34
|
-
else
|
35
|
-
final_parent.delete [obj.rdf_subject, nil, nil]
|
62
|
+
final_parent.statements.each do |statement|
|
63
|
+
final_parent.send(:delete_statement, statement) if
|
64
|
+
statement.subject == source.rdf_subject
|
36
65
|
end
|
37
66
|
end
|
38
67
|
|
68
|
+
##
|
69
|
+
# @return [Enumerator<RDFSource>]
|
70
|
+
def ancestors
|
71
|
+
Ancestors.new(source).to_enum
|
72
|
+
end
|
73
|
+
|
39
74
|
##
|
40
75
|
# @return [#persist!] the last parent in a chain from `parent` (e.g.
|
41
76
|
# the parent's parent's parent). This is the RDF::Mutable that the
|
42
|
-
#
|
77
|
+
# resource will project itself on when persisting.
|
43
78
|
def final_parent
|
44
|
-
|
45
|
-
@final_parent ||= begin
|
46
|
-
current = self.parent
|
47
|
-
while current && current.respond_to?(:parent) && current.parent
|
48
|
-
break if current.parent == current
|
49
|
-
current = current.parent
|
50
|
-
end
|
51
|
-
current
|
52
|
-
end
|
79
|
+
ancestors.to_a.last
|
53
80
|
end
|
54
81
|
|
55
82
|
##
|
@@ -64,12 +91,12 @@ module ActiveTriples
|
|
64
91
|
end
|
65
92
|
|
66
93
|
##
|
67
|
-
# Persists the
|
94
|
+
# Persists the resource to the final parent.
|
68
95
|
#
|
69
96
|
# @return [true] true if the save did not error
|
70
97
|
def persist!
|
71
98
|
erase_old_resource
|
72
|
-
final_parent <<
|
99
|
+
final_parent << source
|
73
100
|
@persisted = true
|
74
101
|
end
|
75
102
|
|
@@ -78,11 +105,59 @@ module ActiveTriples
|
|
78
105
|
#
|
79
106
|
# @return [Boolean]
|
80
107
|
def reload
|
81
|
-
|
82
|
-
|
108
|
+
if loaded? || !persisted?
|
109
|
+
source << final_parent.query(subject: source.rdf_subject)
|
110
|
+
else
|
111
|
+
RepositoryStrategy.new(source).reload
|
112
|
+
source.persist!
|
113
|
+
@loaded=true
|
114
|
+
end
|
115
|
+
@persisted = true unless source.empty?
|
83
116
|
true
|
84
117
|
end
|
85
118
|
|
119
|
+
##
|
120
|
+
# An enumerable over the ancestors of an resource
|
121
|
+
class Ancestors
|
122
|
+
include Enumerable
|
123
|
+
|
124
|
+
# @!attribute source
|
125
|
+
# @return [RDFSource]
|
126
|
+
attr_reader :source
|
127
|
+
|
128
|
+
##
|
129
|
+
# @param source [RDFSource]
|
130
|
+
def initialize(source)
|
131
|
+
@source = source
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# @yield [RDFSource] gives each ancestor to the block
|
136
|
+
# @return [Enumerator<RDFSource>]
|
137
|
+
#
|
138
|
+
# @raise [NilParentError] if `source` does not persist to a parent
|
139
|
+
def each
|
140
|
+
raise NilParentError if
|
141
|
+
!source.persistence_strategy.respond_to?(:parent) ||
|
142
|
+
source.persistence_strategy.parent.nil?
|
143
|
+
|
144
|
+
current = source.persistence_strategy.parent
|
145
|
+
|
146
|
+
if block_given?
|
147
|
+
loop do
|
148
|
+
yield current
|
149
|
+
|
150
|
+
break unless (current.persistence_strategy.respond_to?(:parent) &&
|
151
|
+
current.persistence_strategy.parent)
|
152
|
+
break if current.persistence_strategy.parent == current
|
153
|
+
|
154
|
+
current = current.persistence_strategy.parent
|
155
|
+
end
|
156
|
+
end
|
157
|
+
to_enum
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
86
161
|
class NilParentError < RuntimeError; end
|
87
162
|
class UnmutableParentError < ArgumentError; end
|
88
163
|
end
|