module Tripod::Links::ClassMethods
Public Instance Methods
Define that another resource links to this one. Creates a getter with the name you specify. For this to work, the incoming class needs to define a linked_to relationship. Just creates the relevant getter which always return an array of objects. @example make a method called people which returns Dog objects, via the linked_to :owner field on Dog. We guess the class name based on the linked_from name.
linked_from
:dogs, :owner
@example make a method called doggies which returns Dog objects, via the linked_to :person field on Dog.
linked_from
:doggies, :person, class_name: 'Dog'
@param [ Symbol ] name The name of the link. @param [ Symbol ] incoming_field_name The name of the linked_to relationship on the other class @param [ Hash ] options The options to pass to the field.
@option options [ String ] class_name The name of the class that links to this resource, if we can't guess it from the link name
@return [ LinkedTo ] The generated link
# File lib/tripod/links.rb, line 60 def linked_from(name, incoming_field_name, options = {}) add_linked_from(name, incoming_field_name, options) end
Define a link to another resource. Creates relevant fields and getter/setter methods. Note that the getter only retrives saved resources from the db.
@example Define a link away from resources of this class to resources of class Organisation
linked_to :organisation, 'http://example.com/name'
@example Define a multivalued link away from resources of this class (can be combined with other options)
linked_to :organisations, 'http://example.com/modified_at', multivalued: true
@example Define a link away from resources of this class, specifying the class and the field name that will be generated
linked_to :org, 'http://example.com/modified_at', class_name: 'Organisation', field: my_field
@param [ Symbol ] name The name of the link. @param [ String, RDF::URI ] predicate The predicate for the field. @param [ Hash ] options The options to pass to the field.
@option options [ Boolean ] multivalued Is this a multi-valued field? Default is false. @option options [ String ] class_name The name of the class of resource which we're linking to (normally will derive this from the link name) @option options [ Symbol ] field_name the symbol of the field that will be generated (normally will just add _uri or _uris to the link name)
@return [ LinkedTo
] The generated link
# File lib/tripod/links.rb, line 38 def linked_to(name, predicate, options = {}) add_linked_to(name, predicate, options) end
Protected Instance Methods
# File lib/tripod/links.rb, line 76 def add_linked_from(name, incoming_field_name, options={}) link = linked_from_for(name, incoming_field_name, options) linked_froms[name] = link create_linked_from_getter(name, name, link) end
# File lib/tripod/links.rb, line 66 def add_linked_to(name, predicate, options={}) link = linked_to_for(name, predicate, options) linked_tos[name] = link # create the field (always is_uri) add_field(link.field_name, predicate, options.merge(is_uri: true)) create_linked_to_accessors(name, name) end
# File lib/tripod/links.rb, line 90 def create_linked_from_getter(name, meth, link) generated_methods.module_eval do re_define_method(meth) do klass = Kernel.const_get(link.class_name) incoming_link = klass.linked_tos[link.incoming_field_name.to_sym] incoming_predicate = klass.fields[incoming_link.field_name].predicate # note - this will only find saved ones. klass .where("?uri <#{incoming_predicate.to_s}> <#{self.uri.to_s}>") .resources end end end
# File lib/tripod/links.rb, line 83 def create_linked_to_accessors(name, meth) link = linked_tos[name] create_linked_to_getter(name, meth, link) create_linked_to_setter(name, meth, link) end
# File lib/tripod/links.rb, line 107 def create_linked_to_getter(name, meth, link) generated_methods.module_eval do re_define_method(meth) do klass = Kernel.eval(link.class_name) if link.multivalued? # # TODO: is there a more efficient way of doing this? # note that we can't just do a query like this: # `klass.where('<#{self.uri.to_s}> <#{predicate.to_s}> ?uri').resources` # ... because this will only find saved ones and we want to find resources # whose uris have been set on the resource but not saved to db yet. criteria = klass.where('?uri ?p ?o') uris = read_attribute(link.field_name) filter_str = "" if uris.any? filter_str += " VALUES ?uri { <" filter_str += uris.join("> <") filter_str += "> } " else filter_str += "FILTER (1 = 0)" end criteria.where(filter_str).resources else klass.find(read_attribute(link.field_name)) rescue nil #look it up by it's uri end end end end
# File lib/tripod/links.rb, line 147 def create_linked_to_setter(name, meth, link) generated_methods.module_eval do re_define_method("#{meth}=") do |value| if link.multivalued? val = value.to_a.map{ |v| v.uri } write_attribute( link.field_name, val) else # set the uri from the passed in resource write_attribute( link.field_name, value.uri ) end end end end
instantiates and returns a new LinkedFrom
# File lib/tripod/links.rb, line 164 def linked_from_for(name, incoming_field_name, options) Tripod::Links::LinkedFrom.new(name, incoming_field_name, options) end
instantiates and returns a new LinkTo
# File lib/tripod/links.rb, line 169 def linked_to_for(name, predicate, options) Tripod::Links::LinkedTo.new(name, predicate, options) end