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