lib/active_fedora/aggregation/association.rb in activefedora-aggregation-0.2.1 vs lib/active_fedora/aggregation/association.rb in activefedora-aggregation-0.3.0
- old
+ new
@@ -1,59 +1,84 @@
module ActiveFedora::Aggregation
- class Association
+ class Association < ::ActiveFedora::Associations::IndirectlyContainsAssociation
+ delegate :first, to: :ordered_reader
- # @param [ActiveFedora::Base] parent
- # @param [Reflection] reflection
- # @opts options [String] class_name name of the class in the association
- def initialize(parent, reflection)
- @parent = parent
- @reflection = reflection
+ def ordered_reader
+ OrderedReader.new(owner).to_a
end
- def klass
- @reflection.klass
+ def proxy_class
+ @proxy_class ||= ProxyRepository.new(owner, super)
end
- def == other
- container.to_a == other
+ def options
+ @all_options ||= default_options.merge(super)
end
- def create(&block)
- klass.create(&block).tap do |created|
- container << created
+ # Implements the ids reader method, e.g. foo.item_ids for Foo.has_many :items
+ def ids_reader
+ if loaded?
+ load_target.map do |record|
+ record.id
+ end
+ else
+ proxies = load_proxies_from_solr(fl: 'id, next_ssim, proxyFor_ssim')
+ create_linked_list(@owner.head_id, proxies)
end
- save #causes the (head/tail) pointers on the aggregation to be persisted
end
- def save
- container.save
+ private
+
+ # Write a query to find the proxies
+ def construct_proxy_query
+ @proxy_query ||= begin
+ clauses = { 'proxyIn' => @owner.id }
+ clauses[:has_model] = ActiveFedora::Aggregation::Proxy.to_class_uri
+ ActiveFedora::SolrQueryBuilder.construct_query_for_rel(clauses)
+ end
end
- def target=(vals)
- container.target=(vals)
+ # Finds the proxies
+ # @param opts [Hash] Options that will be passed through to ActiveFedora::SolrService.query.
+ def load_proxies_from_solr(opts = Hash.new)
+ finder_query = construct_proxy_query
+ rows = 1000
+ ActiveFedora::SolrService.query(finder_query, { rows: rows }.merge(opts))
end
- def target_ids=(vals)
- container.target_ids=(vals)
+ # @param [String, NilClass] first_id
+ # @param [Array<Hash>] remainder
+ # @param [Array] list
+ def create_linked_list(first_id, remainder, list=[])
+ return list if remainder.empty?
+
+ index = remainder.find_index { |n| n.fetch('id') == first_id }
+ first = remainder.delete_at(index)
+ next_id = first['next_ssim'].try(:first)
+ create_linked_list(next_id, remainder, list + [first.fetch('proxyFor_ssim').first])
end
- def target_ids
- container.target_ids
+ def default_options
+ { through: default_proxy_class, foreign_key: :target, has_member_relation: reflection.predicate, inserted_content_relation: content_relation }
end
- def container
- @container ||= begin
- ProxyContainer.find_or_initialize(klass.uri_to_id(uri)).tap do |container|
- container.parent = @parent
- end
- end
+ def content_relation
+ default_proxy_class.constantize.reflect_on_association(:target).predicate
end
- def first
- container.first
+ def default_proxy_class
+ 'ActiveFedora::Aggregation::Proxy'
end
- def uri
- @parent.uri + '/files'
+ def raise_on_type_mismatch(record)
+ super
+ if type_validator
+ type_validator.validate!(self,record)
+ end
end
+
+ def type_validator
+ options[:type_validator]
+ end
+
end
end