active-triples 0.7.6 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -3
  3. data/AUTHORS +1 -1
  4. data/CHANGES.md +12 -17
  5. data/Gemfile +2 -0
  6. data/README.md +2 -2
  7. data/active-triples.gemspec +6 -5
  8. data/lib/active_triples.rb +56 -5
  9. data/lib/active_triples/configurable.rb +13 -17
  10. data/lib/active_triples/list.rb +22 -21
  11. data/lib/active_triples/persistable.rb +100 -0
  12. data/lib/active_triples/persistence_strategies/parent_strategy.rb +89 -0
  13. data/lib/active_triples/persistence_strategies/persistence_strategy.rb +77 -0
  14. data/lib/active_triples/persistence_strategies/repository_strategy.rb +78 -0
  15. data/lib/active_triples/properties.rb +2 -1
  16. data/lib/active_triples/rdf_source.rb +94 -159
  17. data/lib/active_triples/relation.rb +17 -45
  18. data/lib/active_triples/repositories.rb +23 -9
  19. data/lib/active_triples/version.rb +1 -1
  20. data/spec/active_triples/configurable_spec.rb +5 -9
  21. data/spec/active_triples/identifiable_spec.rb +1 -18
  22. data/spec/active_triples/list_spec.rb +0 -4
  23. data/spec/active_triples/persistable_spec.rb +93 -0
  24. data/spec/active_triples/persistence_strategies/parent_strategy_spec.rb +93 -0
  25. data/spec/active_triples/persistence_strategies/persistence_strategy_spec.rb +24 -0
  26. data/spec/active_triples/persistence_strategies/repository_strategy_spec.rb +120 -0
  27. data/spec/active_triples/rdf_source_spec.rb +217 -9
  28. data/spec/active_triples/relation_spec.rb +51 -4
  29. data/spec/active_triples/repositories_spec.rb +17 -7
  30. data/spec/active_triples/resource_spec.rb +6 -53
  31. data/spec/active_triples_spec.rb +50 -1
  32. data/spec/spec_helper.rb +5 -1
  33. data/spec/support/active_model_lint.rb +6 -3
  34. data/spec/support/dummies/basic_persistable.rb +13 -0
  35. data/spec/support/shared_examples/persistence_strategy.rb +36 -0
  36. metadata +32 -9
  37. data/spec/active_triples/validations_spec.rb +0 -33
@@ -0,0 +1,89 @@
1
+ module ActiveTriples
2
+ ##
3
+ # Persistence strategy for projecting `RDFSource`s onto the graph of an owning
4
+ # parent source. This allows individual resources to be treated as within the
5
+ # scope of another `RDFSource`.
6
+ class ParentStrategy
7
+ include PersistenceStrategy
8
+
9
+ # @!attribute [r] obj
10
+ # the source to persist with this strategy
11
+ # @!attribute [r] parent
12
+ # the target parent source for persistence
13
+ attr_reader :obj, :parent
14
+
15
+ ##
16
+ # @param obj [RDFSource, RDF::Enumerable] the `RDFSource` (or other
17
+ # `RDF::Enumerable` to persist with the strategy.
18
+ def initialize(obj)
19
+ @obj = obj
20
+ end
21
+
22
+ def destroy
23
+ super { parent.destroy_child(obj) }
24
+ end
25
+
26
+ # Clear out any old assertions in the repository about this node or statement
27
+ # thus preparing to receive the updated assertions.
28
+ def erase_old_resource
29
+ if obj.rdf_subject.node?
30
+ final_parent.statements.each do |statement|
31
+ final_parent.send(:delete_statement, statement) if
32
+ statement.subject == obj.rdf_subject
33
+ end
34
+ else
35
+ final_parent.delete [obj.rdf_subject, nil, nil]
36
+ end
37
+ end
38
+
39
+ ##
40
+ # @return [#persist!] the last parent in a chain from `parent` (e.g.
41
+ # the parent's parent's parent). This is the RDF::Mutable that the
42
+ # object will project itself on when persisting.
43
+ def final_parent
44
+ raise NilParentError if parent.nil?
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
53
+ end
54
+
55
+ ##
56
+ # Sets the target "parent" source for persistence operations.
57
+ #
58
+ # @param parent [RDFSource] source with a persistence strategy,
59
+ # must be mutable.
60
+ def parent=(parent)
61
+ raise UnmutableParentError unless parent.is_a? RDF::Mutable
62
+ raise UnmutableParentError unless parent.mutable?
63
+ @parent = parent
64
+ end
65
+
66
+ ##
67
+ # Persists the object to the final parent.
68
+ #
69
+ # @return [true] true if the save did not error
70
+ def persist!
71
+ erase_old_resource
72
+ final_parent << obj
73
+ @persisted = true
74
+ end
75
+
76
+ ##
77
+ # Repopulates the graph from parent.
78
+ #
79
+ # @return [Boolean]
80
+ def reload
81
+ obj << final_parent.query(subject: obj.rdf_subject)
82
+ @persisted = true unless obj.empty?
83
+ true
84
+ end
85
+
86
+ class NilParentError < RuntimeError; end
87
+ class UnmutableParentError < ArgumentError; end
88
+ end
89
+ end
@@ -0,0 +1,77 @@
1
+ module ActiveTriples
2
+ ##
3
+ # @abstract defines the basic interface for persistence of {RDFSource}'s.
4
+ #
5
+ # A `PersistenceStrategy` has an underlying object (`obj`) which should
6
+ # be an `RDFSource` or equivalent. Strategies can be injected into `RDFSource`
7
+ # instances at runtime to change the target datastore, repository, or object
8
+ # the instance syncs its graph with on save and reload operations.
9
+ #
10
+ # @example Changing a PersistenceStrategy at runtime
11
+ # source = ActiveTriples::Resource.new
12
+ # source.persistence_strategy # => #<ActiveTriples::RepositoryStrategy:...>
13
+ #
14
+ # source.set_persistence_strategy(MyStrategy)
15
+ # source.persistence_strategy # => #<ActiveTriples::MyStrategy:...>
16
+ #
17
+ module PersistenceStrategy
18
+ ##
19
+ # Deletes the resource from the repository.
20
+ #
21
+ # @yield prior to persisting, yields to allow a block that performs
22
+ # deletions in the persisted graph(s).
23
+ # @return [Boolean] true if the resource was sucessfully destroyed
24
+ def destroy(&block)
25
+ obj.clear
26
+ yield if block_given?
27
+ persist!
28
+ @destroyed = true
29
+ end
30
+ alias_method :destroy!, :destroy
31
+
32
+ ##
33
+ # Indicates if the Resource has been destroyed.
34
+ #
35
+ # @return [true, false]
36
+ def destroyed?
37
+ @destroyed ||= false
38
+ end
39
+
40
+ ##
41
+ # Indicates if the resource is persisted to the repository
42
+ #
43
+ # @return [Boolean] true if persisted; else false.
44
+ def persisted?
45
+ @persisted ||= false
46
+ end
47
+
48
+ ##
49
+ # @abstract save the object according to the strategy and set the
50
+ # @persisted flag to `true`
51
+ #
52
+ # @see #persisted?
53
+ #
54
+ # @return [true] true if the save did not error
55
+ def persist!
56
+ raise NotImplementedError, 'Abstract method #persist! is unimplemented'
57
+ end
58
+
59
+ ##
60
+ # @abstract Clear out any old assertions in the repository about this node
61
+ # or statement thus preparing to receive the updated assertions.
62
+ #
63
+ # @return [Boolean]
64
+ def erase_old_resource
65
+ raise NotImplementedError,
66
+ 'Abstract method #erase_old_resource is unimplemented'
67
+ end
68
+
69
+ ##
70
+ # @abstract Repopulate the in-memory graph from the persisted graph
71
+ #
72
+ # @return [Boolean]
73
+ def reload
74
+ raise NotImplementedError, 'Abstract method #reload is unimplemented'
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,78 @@
1
+ module ActiveTriples
2
+ ##
3
+ # Persistence strategy for projecting `RDFSource` to `RDF::Repositories`.
4
+ class RepositoryStrategy
5
+ include PersistenceStrategy
6
+
7
+ # @!attribute [r] obj
8
+ # the source to persist with this strategy
9
+ attr_reader :obj
10
+
11
+ ##
12
+ # @param obj [RDFSource, RDF::Enumerable] the `RDFSource` (or other
13
+ # `RDF::Enumerable` to persist with the strategy.
14
+ def initialize(obj)
15
+ @obj = obj
16
+ end
17
+
18
+ ##
19
+ # Clear out any old assertions in the repository about this node or statement
20
+ # thus preparing to receive the updated assertions.
21
+ def erase_old_resource
22
+ if obj.node?
23
+ repository.statements.each do |statement|
24
+ repository.send(:delete_statement, statement) if
25
+ statement.subject == obj
26
+ end
27
+ else
28
+ repository.delete [obj.to_term, nil, nil]
29
+ end
30
+ end
31
+
32
+ ##
33
+ # Persists the object to the repository
34
+ #
35
+ # @return [true] returns true if the save did not error
36
+ def persist!
37
+ erase_old_resource
38
+ repository << obj
39
+ @persisted = true
40
+ end
41
+
42
+ ##
43
+ # Repopulates the graph from the repository.
44
+ #
45
+ # @return [Boolean]
46
+ def reload
47
+ obj << repository.query(subject: obj)
48
+ @persisted = true unless obj.empty?
49
+ true
50
+ end
51
+
52
+ ##
53
+ # @return [RDF::Repository] The RDF::Repository that the object will project
54
+ # itself on when persisting.
55
+ def repository
56
+ @repository ||= set_repository
57
+ end
58
+
59
+ private
60
+
61
+ ##
62
+ # Finds an appropriate repository from the calling object's configuration.
63
+ # If no repository is configured, builds an ephemeral in-memory
64
+ # repository and 'persists' there.
65
+ #
66
+ # @todo find a way to move this logic out (PersistenceStrategyBuilder?).
67
+ # so the dependency on Repositories is externalized.
68
+ def set_repository
69
+ repo_sym = obj.class.repository || obj.singleton_class.repository
70
+ if repo_sym.nil?
71
+ RDF::Repository.new
72
+ else
73
+ repo = Repositories.repositories[repo_sym]
74
+ repo || raise(RepositoryNotFoundError, "The class #{obj.class} expects a repository called #{repo_sym}, but none was declared")
75
+ end
76
+ end
77
+ end
78
+ end
@@ -60,7 +60,8 @@ module ActiveTriples
60
60
  #
61
61
  # @return [ActiveTriples::NodeConfig]
62
62
  def config_for_term_or_uri(term)
63
- return properties[term.to_s] unless term.kind_of? RDF::Resource
63
+ return properties[term.to_s] unless
64
+ term.is_a?(RDF::Resource) && !term.is_a?(RDFSource)
64
65
  properties.each_value { |v| return v if v.predicate == term.to_uri }
65
66
  end
66
67
 
@@ -1,4 +1,3 @@
1
- require 'deprecation'
2
1
  require 'active_model'
3
2
  require 'active_support/core_ext/hash'
4
3
 
@@ -32,6 +31,11 @@ module ActiveTriples
32
31
  # @see http://www.w3.org/TR/ldp/#dfn-linked-data-platform-rdf-source an
33
32
  # example of the RDF source concept as defined in the LDP specification
34
33
  #
34
+ # An `RDFSource` is an {RDF::Term}---it can be used as a subject, predicate,
35
+ # object, or context in an {RDF::Statement}.
36
+ #
37
+ # @todo complete RDF::Value/RDF::Term/RDF::Resource interfaces
38
+ #
35
39
  # @see ActiveModel
36
40
  # @see RDF::Resource
37
41
  # @see RDF::Queryable
@@ -39,20 +43,15 @@ module ActiveTriples
39
43
  extend ActiveSupport::Concern
40
44
 
41
45
  include NestedAttributes
46
+ include Persistable
42
47
  include Properties
43
48
  include Reflection
44
49
  include RDF::Value
45
- include RDF::Countable
46
- include RDF::Durable
47
- include RDF::Enumerable
48
50
  include RDF::Queryable
49
- include RDF::Mutable
51
+ include ActiveModel::Validations
50
52
  include ActiveModel::Conversion
51
53
  include ActiveModel::Serialization
52
54
  include ActiveModel::Serializers::JSON
53
- include ActiveModel::Validations
54
-
55
- attr_accessor :parent
56
55
 
57
56
  def type_registry
58
57
  @@type_registry ||= {}
@@ -61,7 +60,6 @@ module ActiveTriples
61
60
 
62
61
  included do
63
62
  extend Configurable
64
- extend Deprecation
65
63
  extend ActiveModel::Naming
66
64
  extend ActiveModel::Translation
67
65
  extend ActiveModel::Callbacks
@@ -73,28 +71,11 @@ module ActiveTriples
73
71
  graph.valid?
74
72
  end
75
73
 
76
- delegate :query, :each, :load!, :count, :has_statement?, :to => :@graph
77
-
78
74
  define_model_callbacks :persist
79
-
80
- protected
81
-
82
- def insert_statement(*args)
83
- @graph.send(:insert_statement, *args)
84
- end
85
-
86
- def delete_statement(*args)
87
- @graph.send(:delete_statement, *args)
88
- end
89
75
  end
90
76
 
91
- ##
92
- # Specifies whether the object is currently writable.
93
- #
94
- # @return [true, false]
95
- def writable?
96
- !frozen?
97
- end
77
+ delegate :each, :load!, :count, :has_statement?, :to => :graph
78
+ delegate :to_base, :term?, :escape, :to => :to_term
98
79
 
99
80
  ##
100
81
  # Initialize an instance of this resource class. Defaults to a
@@ -109,11 +90,17 @@ module ActiveTriples
109
90
  # @todo move this logic out to a Builder?
110
91
  def initialize(*args, &block)
111
92
  resource_uri = args.shift unless args.first.is_a?(Hash)
112
- self.parent = args.shift unless args.first.is_a?(Hash)
93
+ unless args.first.is_a?(Hash) || args.empty?
94
+ set_persistence_strategy(ParentStrategy)
95
+ persistence_strategy.parent = args.shift
96
+ else
97
+ set_persistence_strategy(RepositoryStrategy)
98
+ end
113
99
  @graph = RDF::Graph.new(*args, &block)
114
100
  set_subject!(resource_uri) if resource_uri
115
101
 
116
102
  reload
103
+
117
104
  # Append type to graph if necessary.
118
105
  Array(self.class.type).each do |type|
119
106
  unless self.get_values(:type).include?(type)
@@ -122,14 +109,34 @@ module ActiveTriples
122
109
  end
123
110
  end
124
111
 
125
- def final_parent
126
- @final_parent ||= begin
127
- parent = self.parent
128
- while parent && parent.parent && parent.parent != parent
129
- parent = parent.parent
130
- end
131
- parent
132
- end
112
+ ##
113
+ # Compares self to other for {RDF::Term} equality.
114
+ #
115
+ # Delegates the check to `other#==` passing it the term version of `self`.
116
+ #
117
+ # @param other [Object]
118
+ #
119
+ # @see RDF::Term#==
120
+ # @see RDF::Node#==
121
+ # @see RDF::URI#==
122
+ def ==(other)
123
+ other == to_term
124
+ end
125
+
126
+ ##
127
+ # Delegate parent to the persistence strategy if possible
128
+ #
129
+ # @todo establish a better pattern for this. `#parent` has been a public method
130
+ # in the past, but it's probably time to deprecate it.
131
+ def parent
132
+ persistence_strategy.respond_to?(:parent) ? persistence_strategy.parent : nil
133
+ end
134
+
135
+ ##
136
+ # @todo deprecate/remove
137
+ # @see #parent
138
+ def parent=(parent)
139
+ persistence_strategy.respond_to?(:parent=) ? (persistence_strategy.parent = parent) : nil
133
140
  end
134
141
 
135
142
  def attributes
@@ -147,6 +154,8 @@ module ActiveTriples
147
154
  hash
148
155
  end
149
156
 
157
+ ##
158
+ # @return [Class] gives `self#class`
150
159
  def reflections
151
160
  self.class
152
161
  end
@@ -186,26 +195,54 @@ module ActiveTriples
186
195
  end
187
196
 
188
197
  ##
189
- # @return [RDF::URI, RDF::Node] a URI or Node which the resource's
190
- # properties are about.
198
+ # Gives the representation of this
199
+ #
200
+ # @return [RDF::URI, RDF::Node] the URI that identifies this `RDFSource`;
201
+ # or a bnode identifier
202
+ #
203
+ # @see RDF::Term#to_term
191
204
  def rdf_subject
192
205
  @rdf_subject ||= RDF::Node.new
193
206
  end
194
207
  alias_method :to_term, :rdf_subject
195
208
 
196
209
  ##
197
- # A string identifier for the resource
210
+ # @return [String] A string identifier for the resource; '' if the
211
+ # resource is a node
212
+ def humanize
213
+ node? ? '' : rdf_subject.to_s
214
+ end
215
+
216
+ ##
217
+ # @return [RDF::URI] the uri
218
+ def to_uri
219
+ uri? ? rdf_subject : NullURI.new
220
+ end
221
+
222
+ ##
223
+ # @return [String]
224
+ #
225
+ # @see RDF::Node#id
198
226
  def id
199
- node? ? nil : rdf_subject.to_s
227
+ node? ? rdf_subject.id : rdf_subject.to_s
200
228
  end
201
229
 
202
230
  ##
203
- # @return [Boolean]
231
+ # @return [Boolean] true if the Term is a node
232
+ #
204
233
  # @see RDF::Term#node?
205
234
  def node?
206
235
  rdf_subject.node?
207
236
  end
208
237
 
238
+ ##
239
+ # @return [Boolean] true if the Term is a uri
240
+ #
241
+ # @see RDF::Term#uri?
242
+ def uri?
243
+ rdf_subject.uri?
244
+ end
245
+
209
246
  ##
210
247
  # @return [String, nil] the base URI the resource will use when
211
248
  # setting its subject. `nil` if none is used.
@@ -235,14 +272,6 @@ module ActiveTriples
235
272
  node? ? [] : [rdf_subject.to_s]
236
273
  end
237
274
 
238
- ##
239
- # Lists fields registered as properties on the object.
240
- #
241
- # @return [Array<Symbol>] the list of registered properties.
242
- def fields
243
- properties.keys.map(&:to_sym).reject{|x| x == :type}
244
- end
245
-
246
275
  ##
247
276
  # Load data from the #rdf_subject URI. Retrieved data will be
248
277
  # parsed into the Resource's graph from available RDF::Readers
@@ -255,50 +284,11 @@ module ActiveTriples
255
284
  # # => "Oregon State University"
256
285
  #
257
286
  # @return [ActiveTriples::Entity] self
258
- def fetch(*args)
259
- load(rdf_subject, *args)
287
+ def fetch
288
+ load(rdf_subject)
260
289
  self
261
290
  end
262
291
 
263
- def persist!(opts={})
264
- return if @persisting
265
- return false if opts[:validate] && !valid?
266
- @persisting = true
267
- run_callbacks :persist do
268
- raise "failed when trying to persist to non-existant repository or parent resource" unless repository
269
- erase_old_resource
270
- repository << self
271
- @persisted = true
272
- end
273
- @persisting = false
274
- true
275
- end
276
-
277
- ##
278
- # Indicates if the resource is persisted.
279
- #
280
- # @see #persist
281
- # @return [true, false]
282
- def persisted?
283
- @persisted ||= false
284
- return (@persisted and parent.persisted?) if parent
285
- @persisted
286
- end
287
-
288
- ##
289
- # Repopulates the graph from the repository or parent resource.
290
- #
291
- # @return [true, false]
292
- def reload
293
- @relation_cache ||= {}
294
- return false if (node? && self.class.repository != :parent) || !repository
295
- self << repository.query(subject: rdf_subject)
296
- unless empty?
297
- @persisted = true
298
- end
299
- true
300
- end
301
-
302
292
  ##
303
293
  # Adds or updates a property with supplied values.
304
294
  #
@@ -350,7 +340,6 @@ module ActiveTriples
350
340
  get_relation([uri_or_term_property])
351
341
  end
352
342
 
353
-
354
343
  def get_relation(args)
355
344
  @relation_cache ||= {}
356
345
  rel = Relation.new(self, args)
@@ -389,22 +378,6 @@ module ActiveTriples
389
378
  end
390
379
  end
391
380
 
392
- def destroy
393
- clear
394
- persist! if repository
395
- parent.destroy_child(self) if parent
396
- @destroyed = true
397
- end
398
- alias_method :destroy!, :destroy
399
-
400
- ##
401
- # Indicates if the Resource has been destroyed.
402
- #
403
- # @return [true, false]
404
- def destroyed?
405
- @destroyed ||= false
406
- end
407
-
408
381
  def destroy_child(child)
409
382
  statements.each do |statement|
410
383
  delete_statement(statement) if statement.subject == child.rdf_subject || statement.object == child.rdf_subject
@@ -414,7 +387,7 @@ module ActiveTriples
414
387
  ##
415
388
  # Indicates if the record is 'new' (has not yet been persisted).
416
389
  #
417
- # @return [true, false]
390
+ # @return [Boolean]
418
391
  def new_record?
419
392
  not persisted?
420
393
  end
@@ -427,26 +400,20 @@ module ActiveTriples
427
400
  @marked_for_destruction
428
401
  end
429
402
 
430
- protected
431
-
432
- #Clear out any old assertions in the repository about this node or statement
433
- # thus preparing to receive the updated assertions.
434
- def erase_old_resource
435
- if node?
436
- repository.statements.each do |statement|
437
- repository.send(:delete_statement, statement) if statement.subject == rdf_subject
438
- end
439
- else
440
- repository.delete [rdf_subject, nil, nil]
441
- end
442
- end
443
-
444
403
  private
445
404
 
446
405
  def graph
447
406
  @graph
448
407
  end
449
408
 
409
+ ##
410
+ # Lists fields registered as properties on the object.
411
+ #
412
+ # @return [Array<Symbol>] the list of registered properties.
413
+ def fields
414
+ properties.keys.map(&:to_sym).reject{ |x| x == :type }
415
+ end
416
+
450
417
  ##
451
418
  # Returns the properties registered and their configurations.
452
419
  #
@@ -474,21 +441,6 @@ module ActiveTriples
474
441
  predicates.select { |p| !preds.include? p }
475
442
  end
476
443
 
477
- ##
478
- # Given a predicate which has been registered to a property,
479
- # returns the name of the matching property.
480
- #
481
- # @param predicate [RDF::URI]
482
- #
483
- # @return [String, nil] the name of the property mapped to the
484
- # predicate provided
485
- def property_for_predicate(predicate)
486
- properties.each do |property, values|
487
- return property if values[:predicate] == predicate
488
- end
489
- return nil
490
- end
491
-
492
444
  def default_labels
493
445
  [RDF::SKOS.prefLabel,
494
446
  RDF::DC.title,
@@ -497,23 +449,6 @@ module ActiveTriples
497
449
  RDF::SKOS.hiddenLabel]
498
450
  end
499
451
 
500
- ##
501
- # Return the repository (or parent) that this resource should
502
- # write to when persisting.
503
- #
504
- # @return [RDF::Repository, ActiveTriples::Entity] the target
505
- # repository
506
- def repository
507
- @repository ||=
508
- if self.class.repository == :parent
509
- final_parent
510
- else
511
- repo = Repositories.repositories[self.class.repository]
512
- raise RepositoryNotFoundError, "The class #{self.class} expects a repository called #{self.class.repository}, but none was declared" unless repo
513
- repo
514
- end
515
- end
516
-
517
452
  ##
518
453
  # Takes a URI or String and aggressively tries to convert it into
519
454
  # an RDF term. If a String is given, first tries to interpret it
@@ -532,7 +467,7 @@ module ActiveTriples
532
467
  # @return [RDF::Resource] A term
533
468
  # @raise [RuntimeError] no valid RDF term could be built
534
469
  def get_uri(uri_or_str)
535
- return uri_or_str.to_uri if uri_or_str.respond_to? :to_uri
470
+ return uri_or_str.to_term if uri_or_str.respond_to? :to_term
536
471
  return uri_or_str if uri_or_str.is_a? RDF::Node
537
472
  uri_or_node = RDF::Resource.new(uri_or_str)
538
473
  return uri_or_node if uri_or_node.valid?
@@ -550,11 +485,11 @@ module ActiveTriples
550
485
  # which can become a Resource.
551
486
  #
552
487
  # @param uri [#to_uri, String]
553
- # @param vals values to pass as arguments to ::new
488
+ # @param args values to pass as arguments to ::new
554
489
  #
555
490
  # @return [ActiveTriples::Entity] a Resource with the given uri
556
- def from_uri(uri, vals = nil)
557
- new(uri, vals)
491
+ def from_uri(uri, *args)
492
+ new(uri, *args)
558
493
  end
559
494
 
560
495
  ##