Skip to content

Instantly share code, notes, and snippets.

@flyingzumwalt
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flyingzumwalt/02d15b137d4b62a8a3b0 to your computer and use it in GitHub Desktop.
Save flyingzumwalt/02d15b137d4b62a8a3b0 to your computer and use it in GitHub Desktop.
directly_contains_one_association.rb
module ActiveFedora
module Associations
class DirectlyContainsOneAssociation < SingularAssociation #:nodoc:
# Finds objects contained by the container predicate (either the configured has_member_relation or ldp:contains)
# TODO: Refactor this to use solr. Requires indexing ActiveFedora::File objects into solr, including their RDF.type and, if possible, the id of their container
def find_target
query_node = if container_predicate = options[:has_member_relation]
owner
else
container_predicate = ::RDF::Vocab::LDP.contains
container
end
contained_uris = query_node.resource.query(predicate: container_predicate).map { |r| r.object.to_s }
contained_objects = contained_uris.map { |object_uri| klass.find(klass.uri_to_id(object_uri)) }
filtered_objects = contained_objects.select {|o| o.metadata_node.type.include?(options[:type]) }
return filtered_objects.first
end
def replace(record, save = true)
if record
raise_on_type_mismatch(record)
# update_counters(record)
@target ||= find_target
if @target
@target.destroy
end
# set_inverse_instance(record)
insert_record(record)
@updated = true
else
# decrement_counters
remove_keys
end
self.target = record
end
def insert_record(record, force = true, validate = true)
container.save!
if force
record.save!
else
record.save(validate: validate)
end
end
# Finds or initializes the Container that connects the @owner to the @target
def container
@container ||= begin
DirectContainer.find_or_initialize(ActiveFedora::Base.uri_to_id(uri)).tap do |container|
container.parent = @owner
container.has_member_relation = Array(options[:has_member_relation])
container.is_member_of_relation = Array(options[:is_member_of_relation])
end
end
end
# @returns uri identifying the container/association
def uri
raise "Can't get uri. Owner isn't saved" if @owner.new_record?
if @reflection.options[:through]
associated_through_reflection = @owner.class.reflect_on_association(@reflection.options[:through])
raise ArgumentError, "Could not build a uri for the #{@reflection.name} container becuase the #{@reflection.name} association declares :through => #{@reflection.options[:through]} but #{@owner.class} does not actually have an association by that name" if associated_through_reflection.nil? || !associated_through_reflection.name
path_fragment_for_container = associated_through_reflection.name
else
path_fragment_for_container = @reflection.name
end
return "#{@owner.uri}/#{path_fragment_for_container}"
end
protected
def initialize_attributes(record) #:nodoc:
record.uri = ActiveFedora::Base.id_to_uri(container.mint_id)
set_inverse_instance(record)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment