Class: RDFMapper::Model

Inherits:
Object
  • Object
show all
Includes:
Logger
Defined in:
lib/lib/model/base.rb,
lib/lib/model/output.rb,
lib/lib/model/property.rb,
lib/lib/model/attribute.rb,
lib/lib/model/association.rb

Overview

[-]

Defined Under Namespace

Classes: Attribute, Property

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logger

#debug, #fatal, #warn

Constructor Details

#initialize(attributes = {}) {|_self| ... } ⇒ Object

Creates a new instance of a model with specified attributes. Note that attributes include properties as well as associations. It also accepts URIs in addition to symbols:

class Company << RDFMapper::Model
namespace 'http://myschema.com/#'
has_many :people
end

class Person << RDFMapper::Model
namespace 'http://myschema.com/#'
attribute :name, :type => text
belongs_to :company, :predicate => 'http://myschema.com/#employer'
end

The following two examples create identical models:

Person.new(:name => 'John')
Person.new('http://myschema.com/#name' => 'John')

And so do the following two examples:

@company = Company.new(:name => 'MyCo Inc.')

Person.new(:company => @company)
Person.new('http://myschema.com/#employer' => @company)

Parameters:

  • (defaults to: {})

    attributes of the new object

Yields:

  • (_self)

Yield Parameters:



435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/lib/model/base.rb', line 435

def initialize(attributes = {})
  @arbitrary = {}
  @attributes = {}
  @id = nil
  
  self.class.attributes.map do |name, att|
    @attributes[name] = att.value(self)
  end
  
  self.attributes = attributes
  yield self if block_given?
end

Class Method Details

.[](uri) ⇒ Object

Returns a model that subclassed RDFMapper::Model and has specified URI as its rdf:type

class Person < RDFMapper::Model
type 'http://example.org/schema#Person'
end

class Company < RDFMapper::Model
namespace 'http://example.org/schema#'
end

RDFMapper::Model['http://example.org/schema#Person']   #=> Person
RDFMapper::Model['http://example.org/schema#Company']  #=> Company
RDFMapper::Model['http://unknown-url.com/']            #=> nil

Parameters:

Returns:

  • an RDFMapper model



165
166
167
168
169
170
# File 'lib/lib/model/base.rb', line 165

def [](uri)
  return nil if uri.nil?
  @@subclasses.select do |model|
    model.type.to_s == uri.to_s
  end.first
end

.adapter(instance) ⇒ Object .adapterObject

Sets or returns model's connection adapter.

Overloads:

  • .adapter(instance) ⇒ Object

    Sets model's connection adapter

    Parameters:

    • adapter name (:rails, :rest or :sparql)

    • options to pass on to the adapter constructor

  • .adapterObject

    Returns model's connection adapter

Returns:

  • an instance of RDFMapper adapter



139
140
141
142
# File 'lib/lib/model/base.rb', line 139

def adapter(name = nil, options = {})
  return @adapter if name.nil?
  @adapter = RDFMapper::Adapters.register(name, self, options)
end

.all(*args) ⇒ Object

This is an alias for find(:all). You can pass in all the same arguments to this method as you can to find(:all).

See Also:



358
359
360
# File 'lib/lib/model/base.rb', line 358

def all(*args)
  find(:all, *args)
end

.associationsHash

Returns a hash of all associations with their names as keys and RDFMapper::Attribute instances as values.

Returns:



251
252
253
# File 'lib/lib/model/base.rb', line 251

def associations
  Hash[attributes.reject { |name, att| att.property? }]
end

.attribute(name, options = {}) ⇒ Object

Defines an attribute within a model.

Parameters:

  • attribute name

  • attribute type (:text, :uri, :integer, :float)

  • RDF predicate

Returns:

  • instance of RDFMapper::Model::Attribute



264
265
266
267
268
269
270
271
272
273
274
# File 'lib/lib/model/base.rb', line 264

def attribute(name, options = {})
  attributes[name.to_sym] = Attribute.new(self, name.to_sym, options)
  class_eval "    def \#{name}(*args, &block)\n      get_attribute(:\#{name}, *args, &block)\n    end\n    def \#{name}=(value)\n      set_attribute(:\#{name}, value)\n    end\n  EOF\nend\n"

.attributesHash

Returns a hash of all attributes with their names as keys and RDFMapper::Attribute instances as values.

Returns:



231
232
233
# File 'lib/lib/model/base.rb', line 231

def attributes
  @attributes ||= {}
end

.belongs_to(name, options = {}) ⇒ Object

Specifies a one-to-one association with another class. The following methods for retrieval and query of the associated object will be added:

  • association(force_reload = false) -- Returns the associated object. nil is returned if none is found.

  • association=(associate) -- Assigns the associate object.

only if that name can't be inferred from the association name

Parameters:

  • name of the association

  • class name of the association. Use it



52
53
54
# File 'lib/lib/model/association.rb', line 52

def belongs_to(name, options = {})
  attribute(name, options.merge(:association => :belongs_to))
end

.create(attributes) ⇒ Object?

Creates an object and saves it via the assigned adapter. The resulting object is returned whether the object was saved successfully to the database or not.

Parameters:

  • attributes of the new object

Returns:

  • instance of RDFMapper::Model

  • if save was unsuccessful



285
286
287
# File 'lib/lib/model/base.rb', line 285

def create(attributes)
  new(attributes).save(attributes[:id])
end

.find(*args) ⇒ Object

Find operates similarly to Rails' ActiveRecord::Base.find function. It has the same four retrieval approaches:

  • Find by id -- This can either be a specific id, a list of ids, or an array of ids ([5, 6, 10]).

  • Find first -- This will return the first record matched by the options used. These options can either be specific conditions or merely an order. If no record can be matched, nil is returned. Use Model.find(:first, *args) or its shortcut Model.first(*args).

  • Find last - This will return the last record matched by the options used. These options can either be specific conditions or merely an order. If no record can be matched, nil is returned. Use Model.find(:last, *args) or its shortcut Model.last(*args).

  • Find all - This will return all the records matched by the options used. If no records are found, an empty array is returned. Use Model.find(:all, *args) or its shortcut Model.all(*args).



310
311
312
313
314
315
316
317
318
# File 'lib/lib/model/base.rb', line 310

def find(*args)
  options = args.last.is_a?(::Hash) ? args.pop : {}
  case args.first
    when :first   then find_every(options.merge(:limit => 1)).first
    when :last    then find_every(options).last
    when :all     then find_every(options)
    else find_from_ids(args, options)
  end
end

.find_or_create(atts = {}) ⇒ Object?

Either finds or creates an object with the specified ID.

Parameters:

  • attributes of the new object

Returns:

  • instance of RDFMapper::Model

  • if save was unsuccessful



327
328
329
330
# File 'lib/lib/model/base.rb', line 327

def find_or_create(atts = {})
  instance = atts[:id].nil? ? nil : find(atts[:id])
  instance.nil? ? create(atts) : instance
end

.first(*args) ⇒ Object

A convenience wrapper for find(:first, *args). You can pass in all the same arguments to this method as you can to find(:first).

See Also:



338
339
340
# File 'lib/lib/model/base.rb', line 338

def first(*args)
  find(:first, *args)
end

.has?(name, value = nil) ⇒ RDFMapper::Attribute?

Returns RDFMapper::Attribute that is assigned to the specified name. Accepts symbol, string, RDF::URI as a parameter. Value is optional and is used for associations.

class Person < RDFMapper::Model
namespace 'http://example.org/schema#'
attribute :name, :type => :text
has_many :contacts, :predicate => 'http://example.org/schema#has'
has_many :friends, :predicate => 'http://example.org/schema#has'
end

Person.has?(:name)                                          #=> #<RDFMapper::Model::Attribute>
Person.has?('http://example.org/schema#name')               #=> #<RDFMapper::Model::Attribute>
Person.has?('http://example.org/schema#unknown')            #=> nil

Person.has?('http://example.org/schema#has', Contact)       #=> #<RDFMapper::Model::Attribute>
Person.has?('http://example.org/schema#has', Contact.new)   #=> #<RDFMapper::Model::Attribute>
Person.has?(nil, Contact)                                   #=> #<RDFMapper::Model::Attribute>

Parameters:

  • (defaults to: nil)

Returns:

  • if attribute was not found



198
199
200
201
202
203
204
205
206
207
208
# File 'lib/lib/model/base.rb', line 198

def has?(name, value = nil)
  if name.kind_of? String
    return has?(RDF::URI.new(name), value)
  end
  if name.kind_of? Symbol
    return attributes[name]
  end
  attributes.values.select do |att|
    att.matches?(name, value)
  end.first
end

.has_many(name, options = {}) ⇒ Object

Specifies a one-to-many association. The following methods for retrieval and query of collections of associated objects will be added:

  • collection(force_load = false) -- Returns an array of all the associated objects. An empty array is returned if none are found.

  • collection<<(object, ...) -- Adds one or more objects to the collection by setting their foreign keys to the collection‘s primary key.

  • collection.delete(object, ...) -- Removes one or more objects from the collection by removing the association between objects.

  • collection=objects -- Replaces the collections content by deleting and adding objects as appropriate.

  • collection.clear -- Removes every object from the collection.

  • collection.empty? -- Returns true if there are no associated objects.

  • collection.size -- Returns the number of associated objects.

only if that name can't be inferred from the association name

Parameters:

  • name of the association

  • class name of the association. Use it

Returns:

  • instance of RDFMapper::Attribute



34
35
36
# File 'lib/lib/model/association.rb', line 34

def has_many(name, options = {})
  attribute(name, options.merge(:association => :has_many))
end

.last(*args) ⇒ Object

A convenience wrapper for find(:last, *args). You can pass in all the same arguments to this method as you can to find(:last).

See Also:



348
349
350
# File 'lib/lib/model/base.rb', line 348

def last(*args)
  find(:last, *args)
end

.nameString

Returns model's name without modules. Original class name is stored as 'original_name'

module TestModule
class Person < RDFMapper::Model; end
end

Person.name => 'Person'
Person.original_name => 'TestModule::Person'

Returns:



122
123
124
# File 'lib/lib/model/base.rb', line 122

def name
  original_name.split('::').last
end

.namespace(value) ⇒ RDF::Vocabulary .namespaceRDF::Vocabulary

Sets or returns model's namespace. It is intended to operate as a shortcut: model and its attributes will calculate their RDF type and predicates automatically. The following two examples produce identical models:

class Person < RDFMapper::Model
namespace 'http://example.org/schema#'
attribute :name
attribute :age
end

class Person < RDFMapper::Model 
type 'http://example.org/schema#Person'
attribute :name, :predicate => 'http://example.org/schema#name'
attribute :age, :predicate => 'http://example.org/schema#age'
end

Person.type  #=> 'http://xmlns.com/foaf/0.1/Person'

Overloads:

  • .namespace(value) ⇒ RDF::Vocabulary

    Sets model's namespace

    Parameters:

  • .namespaceRDF::Vocabulary

    Returns model's namespace

    Parameters:

Returns:

See Also:



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/lib/model/base.rb', line 47

def namespace(value = nil, options = {})
  @ns = options[:name] || 'myrdf'
  case value
    when NilClass
      @namespace
    when RDF::Vocabulary
      @namespace = value
    else
      @namespace = RDF::Vocabulary.new(value.to_s)
  end
end

.nsString

Returns the short name for model's namespace. Defaults to myrdf

class Person < RDFMapper::Model
namespace 'http://example.org/schema#', :name => 'my'
end

Person.ns        #=> 'example'
Person.to_xml    #=> '<my:Person></my:Person>'

Returns:



71
72
73
# File 'lib/lib/model/base.rb', line 71

def ns
  @ns.to_s || 'myrdf'
end

.original_nameObject

nodoc



15
# File 'lib/lib/model/base.rb', line 15

alias_method :original_name, :name

.propertiesHash

Returns a hash of all properties with their names as keys and RDFMapper::Attribute instances as values.

Returns:



241
242
243
# File 'lib/lib/model/base.rb', line 241

def properties
  Hash[attributes.select { |name, att| att.property? }]
end

.symbol(name, value = nil) ⇒ Symbol?

Returns the association name for the supplied predicate and / or value

Parameters:

  • (defaults to: nil)

Returns:

  • if attribute was not found

See Also:



220
221
222
223
# File 'lib/lib/model/base.rb', line 220

def symbol(name, value = nil)
  att = has?(name, value)
  att.nil? ? nil : att.name
end

.type(value) ⇒ RDF::URI .typeRDF::URI

Sets or returns model's RDF type

class Company < RDFMapper::Model
type RDF::URI.new('http://example.org/schema#Company')
end

class Person < RDFMapper::Model
type 'http://example.org/schema#Person'
end

Company.type  #=>  #<RDF::URI(http://example.org/schema#Company)>
Person.type   #=>  #<RDF::URI(http://example.org/schema#Person)>

Overloads:

  • .type(value) ⇒ RDF::URI

    Sets model's RDF type

    Parameters:

  • .typeRDF::URI

    Parameters:

Returns:

See Also:



99
100
101
102
103
104
105
106
107
# File 'lib/lib/model/base.rb', line 99

def type(value = nil)
  unless value.nil?
    return @type = RDF::URI.new(value.to_s)
  end
  unless @type.nil?
    return @type
  end
  (nil == namespace) == true ? nil : namespace[name]
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?, equal?, new_record?

Compares instances based on their IDs.

Returns:



462
463
464
465
# File 'lib/lib/model/base.rb', line 462

def ==(other)
  return false unless other.kind_of? self.class
  (other.nil? or other.id.nil?) ? false : (id == other.id)
end

#[](name) ⇒ Object

Returns the value of the attribute identified by name after it has been typecast (for example, "2004-12-12" is cast to a date object, like Date.new(2004, 12, 12)). (Alias for the private get_attribute method).

Parameters:

  • attribute name or predicate URI

Returns:

  • instance of a property or an association



479
480
481
482
483
484
# File 'lib/lib/model/base.rb', line 479

def [](name)
  unless name.kind_of? Symbol
    name = self.class.symbol(name)
  end
  name.nil? ? nil : get_attribute(name)
end

#[]=(name, value) ⇒ Object

Updates the attribute identified by name with the specified value. (Alias for the private set_attribute method).

Parameters:

  • attribute name or predicate URI

  • new value of the attribute

Returns:

  • instance of a property or an association



496
497
498
499
500
501
# File 'lib/lib/model/base.rb', line 496

def []=(name, value)
  unless name.kind_of? Symbol
    name = self.class.symbol(name)
  end
  name.nil? ? nil : set_attribute(name, value)
end

#attributes(*args) ⇒ Hash

Returns a hash of all the attributes with their names as keys and the attributes' values as values.

Returns:

  • all attributes of an instance (name => value)



535
536
537
538
539
# File 'lib/lib/model/base.rb', line 535

def attributes(*args)
  Hash[@attributes.keys.map do |name|
    [ name, self[name] ]
  end].merge(@arbitrary).merge({ :id => id })
end

#attributes=(hash) ⇒ Hash

Allows you to set all the attributes at once by passing in a hash with keys matching attribute names or RDF predicates.

Parameters:

  • object's new attributes

Returns:

  • hash of all attributes (name => value)



548
549
550
551
# File 'lib/lib/model/base.rb', line 548

def attributes=(hash)
  return unless hash.kind_of? Hash
  hash.nil? ? nil : hash.each { |name, value| self[name] = value }
end

#foreign_keysHash

Returns a hash of all foreign keys (i.e. URIs) for belongs_to type of associations.

Returns:

  • all foreign keys of an instance (name => uri)



521
522
523
524
525
526
527
# File 'lib/lib/model/base.rb', line 521

def foreign_keys
  Hash[self.class.associations.select do |name, assoc|
    assoc.belongs_to?
  end.map do |name, assoc|
    [ name, @attributes[name].keys ]
  end]
end

#id(*args) ⇒ String

Returns objects's unique ID.

Returns:

  • object's ID (URI)



453
454
455
# File 'lib/lib/model/base.rb', line 453

def id(*args)
  @id.nil? ? nil : @id.dup
end

#inspectString

Developer-friendly representation of the instance.

Returns:



608
609
610
# File 'lib/lib/model/base.rb', line 608

def inspect #nodoc
  "#<%s:%s>" % [self.class, object_id]
end

#new?Boolean

Checks whether the model originated from or was saved to a data source (in other word, whether it has RDF ID).

Returns:



559
560
561
# File 'lib/lib/model/base.rb', line 559

def new?
  id.nil?
end

#properties(*args) ⇒ Hash

Returns a hash of all the properties (i.e. attributes without associations).

Returns:

  • all properties of an instance (name => value)



509
510
511
512
513
# File 'lib/lib/model/base.rb', line 509

def properties(*args)
  Hash[self.class.properties.keys.map do |name|
    [ name, self[name] ]
  end].merge(@arbitrary).merge({ :id => id })
end

#reloadObject

[-]



591
592
593
594
595
596
597
598
599
600
601
# File 'lib/lib/model/base.rb', line 591

def reload
  # Raise error if adapter is unspecified
  check_for_adapter

  if id.nil?
    raise RuntimeError, 'Reload failed. Model has no ID'
  end
  
  self.attributes = self.class.adapter.reload(self)
  self
end

#save(id = nil) ⇒ Object?

Saves the instance. If the model is new, a record gets created via the specified adapter (ID must be supplied in this case), otherwise the existing record gets updated.

Parameters:

  • (defaults to: nil)

    object's ID

Returns:

  • self

  • if save was unsuccessful



574
575
576
577
578
579
580
581
582
583
584
585
586
# File 'lib/lib/model/base.rb', line 574

def save(id = nil)
  # Raise error if adapter is unspecified
  check_for_adapter
        
  if new? and id.nil?
    raise RuntimeError, 'Save failed. ID must be specified'
  end
  if new?
    self.id = id
  end
  self.attributes = self.class.adapter.save(self)
  self
end

#to_statements(options = {}) ⇒ Object

options - class declaration only options - include associations



36
37
38
39
40
41
42
43
44
45
# File 'lib/lib/model/output.rb', line 36

def to_statements(options = {})
  if options[:full]
    atts = attribute_statements(options)
  elsif options[:short]
    return type_statement
  else
    atts = attribute_statements
  end
  type_statement + atts
end

#to_triples(options = {}) ⇒ Object

[-]



26
27
28
29
30
# File 'lib/lib/model/output.rb', line 26

def to_triples(options = {})
  to_statements(options).map do |statement|
    [ statement[:subject], statement[:predicate], statement[:object] ]
  end
end

#to_xml(options = {}) ⇒ String

RDF XML representaion of the instance.

Parameters:

  • (defaults to: {})

    [TODO]

Returns:



12
13
14
15
16
17
18
19
20
21
# File 'lib/lib/model/output.rb', line 12

def to_xml(options = {})
  RDF::Writer.for(:xml).buffer({ :declaration => false }) do |writer|
    if self.class.namespace
      writer.namespace!(self.class.namespace, self.class.ns)
    end
    to_triples.each do |triple|
      writer << triple
    end
  end
end