Module: Spira::Persistence::ClassMethods
- Defined in:
- lib/spira/persistence.rb
Instance Method Summary collapse
- #all(*args) ⇒ Object
-
#count ⇒ Integer
The number of URIs projectable as a given class in the repository.
-
#create(attributes = nil, options = {}, &block) ⇒ Object
Creates an object (or multiple objects) and saves it to the database, if validations pass.
-
#each(*args) ⇒ Object
(also: #find_each)
Enumerate over all resources projectable as this class.
-
#find(scope, *args) ⇒ Spira::Base, Array
Simple finder method.
- #first(*args) ⇒ Object
-
#for(identifier, attributes = {}) {|self| ... } ⇒ Spira::Base
(also: #[])
Create a new projection instance of this class for the given URI.
-
#id_for(identifier) ⇒ RDF::URI, RDF::Node
Creates a URI or RDF::Node based on a potential base_uri and string, URI, or Node, or Addressable::URI.
-
#project(subject, attributes = {}, &block) ⇒ Spira::Base
Create a new instance with the given subject without any modification to the given subject at all.
-
#repository ⇒ RDF::Repository?
The current repository for this class.
Instance Method Details
#all(*args) ⇒ Object
36 37 38 |
# File 'lib/spira/persistence.rb', line 36 def all(*args) find(:all, *args) end |
#count ⇒ Integer
The number of URIs projectable as a given class in the repository. This method is only valid for classes which declare a type
with the type
method in the Resource.
100 101 102 |
# File 'lib/spira/persistence.rb', line 100 def count each.count end |
#create(attributes = nil, options = {}, &block) ⇒ Object
Creates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not.
The attributes
parameter can be either be a Hash or an Array of Hashes. These Hashes describe the attributes on the objects that are to be created.
create
respects mass-assignment security and accepts either :as
or :without_protection
options in the options
parameter.
==== Examples # Create a single new object User.create(first_name: ‘Jamie’)
# Create a single new object using the :admin mass-assignment security role User.create({ first_name: ‘Jamie’, is_admin: true }, as: :admin)
# Create a single new object bypassing mass-assignment security User.create({ first_name: ‘Jamie’, is_admin: true }, without_protection: true)
# Create an Array of new objects User.create([{ first_name: ‘Jamie’ }, { first_name: ‘Jeremy’ }])
# Create a single object and pass it into a block to set other attributes. User.create(first_name: ‘Jamie’) do |u| u.is_admin = false end
# Creating an Array of new objects using a block, where the block is executed for each object: User.create([{ first_name: ‘Jamie’ }, { first_name: ‘Jeremy’ }]) do |u| u.is_admin = false end
135 136 137 138 139 140 141 142 143 |
# File 'lib/spira/persistence.rb', line 135 def create(attributes = nil, = {}, &block) if attributes.is_a?(Array) attributes.collect { |attr| create(attr, , &block) } else object = new(attributes, , &block) object.save object end end |
#each {|instance| ... } ⇒ Void #each ⇒ Enumerator Also known as: find_each
Enumerate over all resources projectable as this class. This method is only valid for classes which declare a type
with the type
method in the Resource.
Note that the instantiated records are “promises” not real instances.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/spira/persistence.rb', line 60 def each(*args) raise Spira::NoTypeError, "Cannot count a #{self} without a reference type URI" unless type = args. conditions = .delete(:conditions) || {} raise Spira::SpiraError, "Cannot accept :type in query conditions" if conditions.delete(:type) || conditions.delete("type") if block_given? limit = [:limit] || -1 offset = [:offset] || 0 # TODO: ideally, all types should be joined in a conjunction # within "conditions_to_query", but since RDF::Query # cannot handle such patterns, we iterate across types "manually" types.each do |tp| break if limit.zero? q = conditions_to_query(conditions.merge(type: tp)) repository.query(q) do |solution| break if limit.zero? if offset.zero? yield unserialize(solution[:subject]) limit -= 1 else offset -= 1 end end end else enum_for(:each, *args) end end |
#find(scope, *args) ⇒ Spira::Base, Array
Simple finder method.
25 26 27 28 29 30 31 32 33 34 |
# File 'lib/spira/persistence.rb', line 25 def find(scope, *args) case scope when :first find_each(*args).first when :all find_all(*args) else instantiate_record(scope) end end |
#first(*args) ⇒ Object
40 41 42 |
# File 'lib/spira/persistence.rb', line 40 def first(*args) find(:first, *args) end |
#for(uri, attributes = {}) ⇒ Spira::Base #for(identifier, attributes = {}) ⇒ Spira::Base Also known as: []
Create a new projection instance of this class for the given URI. If a class has a base_uri given, and the argument is not an RDF::URI
, the given identifier will be appended to the base URI.
Spira does not have ‘find’ or ‘create’ functions. As RDF identifiers are globally unique, they all simply ‘are’.
On calling for
, a new projection is created for the given URI. The first time access is attempted on a field, the repository will be queried for existing attributes, which will be used for the given URI. Underlying repositories are not accessed at the time of calling for
.
A class with a base URI may still be projected for any URI, whether or not it uses the given resource class’ base URI.
given in the attributes. have a base URI.
175 176 177 |
# File 'lib/spira/persistence.rb', line 175 def for(identifier, attributes = {}, &block) self.project(id_for(identifier), attributes, &block) end |
#id_for(identifier) ⇒ RDF::URI, RDF::Node
Creates a URI or RDF::Node based on a potential base_uri and string, URI, or Node, or Addressable::URI. If not a URI or Node, the given identifier should be a string representing an absolute URI, or something responding to to_s which can be appended to a base URI, which this class must have.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/spira/persistence.rb', line 211 def id_for(identifier) case # Absolute URI's go through unchanged when identifier.is_a?(RDF::URI) && identifier.absolute? identifier # We don't have a base URI to join this fragment with, so go ahead and instantiate it as-is. when identifier.is_a?(RDF::URI) && self.base_uri.nil? identifier # Blank nodes go through unchanged when identifier.respond_to?(:node?) && identifier.node? identifier # Anything that can be an RDF::URI, we re-run this case statement # on it for the fragment logic above. when identifier.respond_to?(:to_uri) && !identifier.is_a?(RDF::URI) id_for(identifier.to_uri) # see comment with #to_uri above, this might be a fragment else uri = identifier.is_a?(RDF::URI) ? identifier : RDF::URI.intern(identifier.to_s) case when uri.absolute? uri when self.base_uri.nil? raise ArgumentError, "Cannot create identifier for #{self} by String without base_uri; an RDF::URI is required" else separator = self.base_uri.to_s[-1,1] =~ /(\/|#)/ ? '' : '/' RDF::URI.intern(self.base_uri.to_s + separator + identifier.to_s) end end end |
#project(subject, attributes = {}, &block) ⇒ Spira::Base
Create a new instance with the given subject without any modification to the given subject at all. This method exists to provide an entry point for implementing classes that want to create a more intelligent .for and/or .id_for for their given use cases, such as simple string appending to base URIs or calculated URIs from other representations.
194 195 196 |
# File 'lib/spira/persistence.rb', line 194 def project(subject, attributes = {}, &block) new(attributes.merge(_subject: subject), &block) end |
#repository ⇒ RDF::Repository?
The current repository for this class
11 12 13 |
# File 'lib/spira/persistence.rb', line 11 def repository Spira.repository || raise(NoRepositoryError) end |