Module: Ladder::Resource::ClassMethods

Defined in:
lib/ladder/resource.rb

Instance Method Summary collapse

Instance Method Details

#new_from_graph(graph, objects = {}, pattern = nil) ⇒ Ladder::Resource?

Create a new instance of this class, populated with values and related objects from a given RDF::Graph for this model.

By default, the graph will be traversed starting with the first node that matches the same RDF.type as this class; however, an optional RDF::Queryable pattern can be provided, @see RDF::Queryable#query

As nodes are traversed in the graph, the instantiated objects will be added to a Hash that is passed recursively, in order to prevent infinite traversal in the case of cyclic graphs.

Parameters:

  • graph (RDF::Graph)

    an RDF::Graph to traverse

  • objects (Hash) (defaults to: {})

    a keyed Hash of already-created objects in the graph

  • pattern (RDF::Query, RDF::Statement, Array(RDF::Term), Hash) (defaults to: nil)

    a query pattern

Returns:



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/ladder/resource.rb', line 189

def new_from_graph(graph, objects = {}, pattern = nil)
  # Default to getting the first object in the graph with the same RDF type as this class
  pattern ||= [nil, RDF.type, resource_class.type]

  root_subject = graph.query(pattern).first_subject
  return unless root_subject

  # If the subject is an existing model, just retrieve it
  new_object = Ladder::Resource.from_uri(root_subject) if root_subject.is_a? RDF::URI
  new_object ||= new

  # Add object to stack for recursion
  objects[root_subject] = new_object

  graph.query([root_subject]).each_statement do |statement|
    next if objects[statement.object]

    # TODO: If the object is a list, process members individually
    # list = RDF::List.new statement.object, graph
    # binding.pry unless list.empty?

    # If the object is a BNode, dereference the relation
    if statement.object.is_a? RDF::Node
      klass = new_object.klass_from_predicate(statement.predicate)
      next unless klass

      object = klass.new_from_graph(graph, objects)
      next unless object

      objects[statement.object] = object
      new_object.send(:<<, statement) { object }
    else
      new_object << statement
    end
  end # end each_statement

  new_object
end

#property(field_name, opts = {}) ⇒ ActiveTriples::Resource

Define a Mongoid field/relation on the class as well as an RDF property on the delegated resource

Parameters:

  • field_name (String)

    ActiveModel attribute name for the field

  • opts (Hash) (defaults to: {})

    options to pass to Mongoid / ActiveTriples

Returns:

  • (ActiveTriples::Resource)

    a modified resource

See Also:

  • ActiveTriples::Resource#property
  • ActiveTriples::Properties


159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/ladder/resource.rb', line 159

def property(field_name, opts = {})
  if opts[:class_name]
    mongoid_opts = { autosave: true, index: true }.merge(opts.except(:predicate, :multivalue))
    has_and_belongs_to_many(field_name, mongoid_opts) unless relations.keys.include? field_name.to_s
  else
    mongoid_opts = { localize: true }.merge(opts.except(:predicate, :multivalue))
    field(field_name, mongoid_opts) unless fields[field_name.to_s]
  end

  opts.except!(*mongoid_opts.keys)

  super
end