Class: Spira::Base

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Callbacks, ActiveModel::Naming, Reflections, Resource
Includes:
ActiveModel::Conversion, ActiveModel::Dirty, ActiveModel::Serialization, RDF, RDF::Enumerable, RDF::Queryable, Persistence, Serialization, Types, Utils, Validations
Defined in:
lib/spira/base.rb

Overview

Spira::Base aims to perform similar to ActiveRecord::Base You should inherit your models from it.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Reflections

reflect_on_association, reflections

Methods included from Resource

configure, has_many, property

Methods included from Serialization

#encode_with, #init_with

Methods included from Validations

#perform_validations, #save, #save!, #valid?

Methods included from Persistence

#count, #destroy, #destroy!, #destroyed?, #each, #new_record?, #persisted?, #save, #save!, #update_attributes

Methods included from Utils

#rename!

Constructor Details

#initialize(props = {}, options = {}) {|self| ... } ⇒ Base

Initialize a new Spira::Base instance of this resource class using a new blank node subject. Accepts a hash of arguments for initial attributes. To use a URI or existing blank node as a subject, use Spira.for instead.

Parameters:

  • props (Hash{Symbol => Any}) (defaults to: {})

    Default attributes for this instance

Yields:

  • (self)

    Executes a given block

Yield Parameters:

  • self (self)

    The newly created instance

See Also:


118
119
120
121
122
123
124
125
# File 'lib/spira/base.rb', line 118

def initialize(props = {}, options = {})
  @subject = props.delete(:_subject) || RDF::Node.new
  @attrs = {}

  reload props

  yield self if block_given?
end

Class Attribute Details

.propertiesObject (readonly)

Returns the value of attribute properties


36
37
38
# File 'lib/spira/base.rb', line 36

def properties
  @properties
end

.reflectionsObject (readonly)

Returns the value of attribute reflections


36
37
38
# File 'lib/spira/base.rb', line 36

def reflections
  @reflections
end

Instance Attribute Details

#subjectRDF::URI (readonly)

This instance's URI.

Returns:


33
34
35
# File 'lib/spira/base.rb', line 33

def subject
  @subject
end

Class Method Details

.base_uriVoid

The base URI for this class. Attempts to create instances for non-URI objects will be appended to this base URI.

Returns:

  • (Void)

47
48
49
50
51
# File 'lib/spira/base.rb', line 47

def base_uri
  # should be redefined in children, if required
  # see also Spira::Resource.configure :base_uri option
  nil
end

.default_vocabularyVoid

The default vocabulary for this class. Setting a default vocabulary will allow properties to be defined without a :predicate option. Predicates will instead be created by appending the property name to the given string.

Returns:

  • (Void)

60
61
62
63
64
# File 'lib/spira/base.rb', line 60

def default_vocabulary
  # should be redefined in children, if required
  # see also Spira::Resource.configure :default_vocabulary option
  nil
end

.serialize(node, options = {}) ⇒ Object


66
67
68
69
70
71
72
73
74
# File 'lib/spira/base.rb', line 66

def serialize(node, options = {})
  if node.respond_to?(:subject)
    node.subject
  elsif node.respond_to?(:blank?) && node.blank?
    nil
  else
    raise TypeError, "cannot serialize #{node.inspect} as a Spira resource"
  end
end

.typesObject


38
39
40
# File 'lib/spira/base.rb', line 38

def types
  Set.new
end

.unserialize(value, options = {}) ⇒ Object


76
77
78
79
80
81
82
83
84
# File 'lib/spira/base.rb', line 76

def unserialize(value, options = {})
  if value.respond_to?(:blank?) && value.blank?
    nil
  else
    # Spira resources are instantiated as "promised"
    # to avoid instantiation loops in case of resource-to-resource relations.
    promise { instantiate_record(value) }
  end
end

Instance Method Details

#==(other) ⇒ Object

Compare this instance with another instance. The comparison is done on an RDF level, and will work across subclasses as long as the attributes are the same.


192
193
194
195
196
197
198
199
200
201
202
# File 'lib/spira/base.rb', line 192

def ==(other)
  # TODO: define behavior for equality on subclasses.
  # TODO: should we compare attributes here?
  if self.class == other.class
    subject == other.uri
  elsif other.is_a?(RDF::Enumerable)
    self.isomorphic_with?(other)
  else
    false
  end
end

#assign_attributes(attrs) ⇒ Object

Assign attributes to the resource without persisting it.


279
280
281
282
283
284
# File 'lib/spira/base.rb', line 279

def assign_attributes(attrs)
  attrs.each do |name, value|
    attribute_will_change!(name.to_s)
    send "#{name}=", value
  end
end

#attributesObject

Returns the attributes


128
129
130
# File 'lib/spira/base.rb', line 128

def attributes
  @attrs
end

#copy(new_subject) ⇒ Spira::Base

Returns a new instance of this class with the new subject instead of self.subject

Parameters:

  • new_subject (RDF::Resource)

Returns:


262
263
264
# File 'lib/spira/base.rb', line 262

def copy(new_subject)
  self.class.new(@attrs.merge(:_subject => new_subject))
end

#copy!(new_subject) ⇒ Spira::Base, String

Returns a new instance of this class with the new subject instead of self.subject after saving the new copy to the repository.

Parameters:

  • new_subject (RDF::Resource)

Returns:


272
273
274
# File 'lib/spira/base.rb', line 272

def copy!(new_subject)
  copy(new_subject).save!
end

#freezeObject

Freeze the attributes hash such that associations are still accessible, even on destroyed records.


133
134
135
# File 'lib/spira/base.rb', line 133

def freeze
  @attrs.freeze; self
end

#frozen?Boolean

Returns +true+ if the attributes hash has been frozen.

Returns:


138
139
140
# File 'lib/spira/base.rb', line 138

def frozen?
  @attrs.frozen?
end

#idObject


102
103
104
# File 'lib/spira/base.rb', line 102

def id
  new_record? ? nil : subject.path.split(/\//).last
end

#inspectObject

A developer-friendly view of this projection


182
183
184
# File 'lib/spira/base.rb', line 182

def inspect
  "<#{self.class}:#{self.object_id} @subject: #{@subject}>"
end

#node?true, false

Returns true if the subject associated with this instance is a blank node.

Returns:

  • (true, false)

243
244
245
# File 'lib/spira/base.rb', line 243

def node?
  subject.node?
end

#reload(props = {}) ⇒ Object

Assign all attributes from the given hash.


164
165
166
167
168
169
# File 'lib/spira/base.rb', line 164

def reload(props = {})
  reset_changes
  super
  assign_attributes(props)
  self
end

#respond_to?(*args) ⇒ Boolean

Returns true for :to_uri if this instance's subject is a URI, and false if it is not. Returns true for :to_node if this instance's subject is a Node, and false if it is not. Calls super otherwise.

Returns:


209
210
211
212
213
214
215
216
217
218
# File 'lib/spira/base.rb', line 209

def respond_to?(*args)
  case args[0]
  when :to_uri
    subject.respond_to?(:to_uri)
  when :to_node
    subject.node?
  else
    super(*args)
  end
end

#to_nodeRDF::Node

Returns the Node subject of this resource, if available. If this resource's subject is a URI, raises a NoMethodError.

Returns:

Raises:

  • (NoMethodError)

253
254
255
# File 'lib/spira/base.rb', line 253

def to_node
  subject.node? ? subject : (raise NoMethodError, "No such method: :to_uri (this instance's subject is not a URI)")
end

#to_rdfRDF::Enumerable

Returns the RDF representation of this resource.

Returns:

  • (RDF::Enumerable)

175
176
177
# File 'lib/spira/base.rb', line 175

def to_rdf
  self
end

#to_uriRDF::URI

Returns the URI representation of this resource, if available. If this resource's subject is a BNode, raises a NoMethodError.

Returns:

Raises:

  • (NoMethodError)

235
236
237
# File 'lib/spira/base.rb', line 235

def to_uri
  uri || (raise NoMethodError, "No such method: :to_uri (this instance's subject is not a URI)")
end

#typenil, RDF::URI

The RDF.type associated with this class.

This just takes a first type from "types" list, so make sure you know what you're doing if you use it.

Returns:

  • (nil, RDF::URI)

    The RDF type associated with this instance's class.


149
150
151
# File 'lib/spira/base.rb', line 149

def type
  self.class.type
end

#typesnil, RDF::URI

All RDF.type nodes associated with this class.

Returns:

  • (nil, RDF::URI)

    The RDF type associated with this instance's class.


157
158
159
# File 'lib/spira/base.rb', line 157

def types
  self.class.types
end

#uriRDF::URI?

Returns the RDF::URI associated with this instance if this instance's subject is an RDF::URI, and nil otherwise.

Returns:


225
226
227
# File 'lib/spira/base.rb', line 225

def uri
  subject.respond_to?(:to_uri) ? subject : nil
end