active-fedora 9.10.0.pre2 → 9.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/History.txt +141 -0
- data/lib/active_fedora/associations/association.rb +38 -12
- data/lib/active_fedora/associations/association_scope.rb +6 -2
- data/lib/active_fedora/associations/basic_contains_association.rb +2 -3
- data/lib/active_fedora/associations/belongs_to_association.rb +23 -4
- data/lib/active_fedora/associations/builder/association.rb +37 -56
- data/lib/active_fedora/associations/builder/belongs_to.rb +27 -1
- data/lib/active_fedora/associations/builder/collection_association.rb +33 -2
- data/lib/active_fedora/associations/builder/contains.rb +3 -3
- data/lib/active_fedora/associations/builder/directly_contains.rb +1 -7
- data/lib/active_fedora/associations/builder/directly_contains_one.rb +20 -17
- data/lib/active_fedora/associations/builder/has_and_belongs_to_many.rb +1 -1
- data/lib/active_fedora/associations/builder/has_many.rb +2 -43
- data/lib/active_fedora/associations/builder/indirectly_contains.rb +1 -7
- data/lib/active_fedora/associations/builder/property.rb +2 -13
- data/lib/active_fedora/associations/builder/singular_association.rb +2 -6
- data/lib/active_fedora/associations/builder/singular_property.rb +2 -3
- data/lib/active_fedora/associations/collection_association.rb +6 -14
- data/lib/active_fedora/associations/directly_contains_one_association.rb +1 -2
- data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +1 -1
- data/lib/active_fedora/associations/has_many_association.rb +23 -0
- data/lib/active_fedora/attached_files.rb +1 -1
- data/lib/active_fedora/core.rb +2 -1
- data/lib/active_fedora/errors.rb +13 -0
- data/lib/active_fedora/file.rb +16 -1
- data/lib/active_fedora/file/attributes.rb +6 -6
- data/lib/active_fedora/reflection.rb +200 -76
- data/lib/active_fedora/version.rb +1 -1
- data/lib/active_fedora/with_metadata/metadata_node.rb +2 -1
- data/lib/generators/active_fedora/config/fedora/fedora_generator.rb +4 -0
- data/lib/generators/active_fedora/config/fedora/templates/.fcrepo_wrapper +3 -0
- data/lib/generators/active_fedora/config/solr/solr_generator.rb +4 -0
- data/lib/generators/active_fedora/config/solr/templates/.solr_wrapper +5 -0
- data/spec/integration/attached_files_spec.rb +4 -4
- data/spec/integration/file_spec.rb +1 -1
- data/spec/integration/om_datastream_spec.rb +6 -6
- data/spec/unit/collection_proxy_spec.rb +1 -1
- data/spec/unit/file_spec.rb +19 -0
- data/spec/unit/has_and_belongs_to_many_association_spec.rb +4 -4
- data/spec/unit/has_many_association_spec.rb +2 -2
- data/spec/unit/reflection_spec.rb +2 -2
- metadata +6 -4
    
        data/lib/active_fedora/errors.rb
    CHANGED
    
    | @@ -44,6 +44,19 @@ module ActiveFedora #:nodoc: | |
| 44 44 | 
             
              class AssociationNotFoundError < ConfigurationError #:nodoc:
         | 
| 45 45 | 
             
              end
         | 
| 46 46 |  | 
| 47 | 
            +
              # This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
         | 
| 48 | 
            +
              # (has_many, has_one) when there is at least 1 child associated instance.
         | 
| 49 | 
            +
              # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
         | 
| 50 | 
            +
              class DeleteRestrictionError < ActiveFedoraError #:nodoc:
         | 
| 51 | 
            +
                def initialize(name = nil)
         | 
| 52 | 
            +
                  if name
         | 
| 53 | 
            +
                    super("Cannot delete record because of dependent #{name}")
         | 
| 54 | 
            +
                  else
         | 
| 55 | 
            +
                    super("Delete restriction error.")
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 47 60 | 
             
              # Raised when ActiveFedora cannot find the predicate corresponding to the given property
         | 
| 48 61 | 
             
              # in the predicate registy
         | 
| 49 62 | 
             
              class UnregisteredPredicateError < ActiveFedoraError
         | 
    
        data/lib/active_fedora/file.rb
    CHANGED
    
    | @@ -63,6 +63,12 @@ module ActiveFedora | |
| 63 63 | 
             
                  end
         | 
| 64 64 | 
             
                end
         | 
| 65 65 |  | 
| 66 | 
            +
                def save
         | 
| 67 | 
            +
                  super.tap do
         | 
| 68 | 
            +
                    metadata.save if metadata.changed?
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 66 72 | 
             
                def described_by
         | 
| 67 73 | 
             
                  raise "#{self} isn't persisted yet" if new_record?
         | 
| 68 74 | 
             
                  links['describedby'].first
         | 
| @@ -114,6 +120,7 @@ module ActiveFedora | |
| 114 120 | 
             
                def attribute_will_change!(attr)
         | 
| 115 121 | 
             
                  if attr == 'content'
         | 
| 116 122 | 
             
                    changed_attributes['content'] = true
         | 
| 123 | 
            +
                  elsif attr == 'type'
         | 
| 117 124 | 
             
                  else
         | 
| 118 125 | 
             
                    super
         | 
| 119 126 | 
             
                  end
         | 
| @@ -138,7 +145,15 @@ module ActiveFedora | |
| 138 145 | 
             
                end
         | 
| 139 146 |  | 
| 140 147 | 
             
                def changed?
         | 
| 141 | 
            -
                  super || content_changed?
         | 
| 148 | 
            +
                  super || content_changed? || metadata_changed?
         | 
| 149 | 
            +
                end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                def metadata_changed?
         | 
| 152 | 
            +
                  if new_record? || links['describedby'].blank?
         | 
| 153 | 
            +
                    false
         | 
| 154 | 
            +
                  else
         | 
| 155 | 
            +
                    metadata.changed?
         | 
| 156 | 
            +
                  end
         | 
| 142 157 | 
             
                end
         | 
| 143 158 |  | 
| 144 159 | 
             
                def inspect
         | 
| @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            module ActiveFedora::File::Attributes
         | 
| 2 | 
            -
              attr_writer :mime_type
         | 
| 3 | 
            -
             | 
| 4 2 | 
             
              def mime_type
         | 
| 5 | 
            -
                 | 
| 3 | 
            +
                fetch_mime_type
         | 
| 6 4 | 
             
              end
         | 
| 7 5 |  | 
| 6 | 
            +
              delegate :mime_type=, to: :metadata
         | 
| 7 | 
            +
             | 
| 8 8 | 
             
              def original_name
         | 
| 9 9 | 
             
                @original_name ||= fetch_original_name
         | 
| 10 10 | 
             
              end
         | 
| @@ -25,7 +25,7 @@ module ActiveFedora::File::Attributes | |
| 25 25 | 
             
              end
         | 
| 26 26 |  | 
| 27 27 | 
             
              def dirty_size
         | 
| 28 | 
            -
                content.size if  | 
| 28 | 
            +
                content.size if content_changed? && content.respond_to?(:size)
         | 
| 29 29 | 
             
              end
         | 
| 30 30 |  | 
| 31 31 | 
             
              def size
         | 
| @@ -68,8 +68,8 @@ module ActiveFedora::File::Attributes | |
| 68 68 | 
             
                end
         | 
| 69 69 |  | 
| 70 70 | 
             
                def fetch_mime_type
         | 
| 71 | 
            -
                  return default_mime_type if new_record?
         | 
| 72 | 
            -
                   | 
| 71 | 
            +
                  return default_mime_type if new_record? && metadata.mime_type.blank?
         | 
| 72 | 
            +
                  metadata.mime_type.first
         | 
| 73 73 | 
             
                end
         | 
| 74 74 |  | 
| 75 75 | 
             
                def fetch_original_name
         | 
| @@ -3,29 +3,35 @@ module ActiveFedora | |
| 3 3 | 
             
                extend ActiveSupport::Concern
         | 
| 4 4 |  | 
| 5 5 | 
             
                included do
         | 
| 6 | 
            -
                  class_attribute : | 
| 7 | 
            -
                  self. | 
| 6 | 
            +
                  class_attribute :_reflections
         | 
| 7 | 
            +
                  self._reflections = {}
         | 
| 8 8 | 
             
                end
         | 
| 9 9 |  | 
| 10 | 
            -
                 | 
| 11 | 
            -
                   | 
| 10 | 
            +
                def reflections
         | 
| 11 | 
            +
                  self.class.reflections
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                class << self
         | 
| 15 | 
            +
                  def create(macro, name, scope, options, active_fedora)
         | 
| 12 16 | 
             
                    klass = case macro
         | 
| 13 17 | 
             
                            when :has_many, :belongs_to, :has_and_belongs_to_many, :contains, :directly_contains, :directly_contains_one, :indirectly_contains
         | 
| 14 18 | 
             
                              AssociationReflection
         | 
| 15 19 | 
             
                            when :rdf, :singular_rdf
         | 
| 16 20 | 
             
                              RDFPropertyReflection
         | 
| 17 21 | 
             
                            end
         | 
| 18 | 
            -
                    reflection = klass.new(macro, name, options, active_fedora)
         | 
| 19 | 
            -
                    add_reflection name, reflection
         | 
| 20 | 
            -
             | 
| 22 | 
            +
                    reflection = klass.new(macro, name, scope, options, active_fedora)
         | 
| 23 | 
            +
                    add_reflection(active_fedora, name, reflection)
         | 
| 21 24 | 
             
                    reflection
         | 
| 22 25 | 
             
                  end
         | 
| 23 26 |  | 
| 24 | 
            -
                  def add_reflection(name, reflection)
         | 
| 27 | 
            +
                  def add_reflection(active_fedora, name, reflection)
         | 
| 28 | 
            +
                    active_fedora.clear_reflections_cache
         | 
| 25 29 | 
             
                    # FIXME: this is where the problem with association_spec is caused (key is string now)
         | 
| 26 | 
            -
                     | 
| 30 | 
            +
                    active_fedora._reflections = active_fedora._reflections.merge(name => reflection)
         | 
| 27 31 | 
             
                  end
         | 
| 32 | 
            +
                end
         | 
| 28 33 |  | 
| 34 | 
            +
                module ClassMethods
         | 
| 29 35 | 
             
                  # Returns a hash containing all AssociationReflection objects for the current class.
         | 
| 30 36 | 
             
                  # Example:
         | 
| 31 37 | 
             
                  #
         | 
| @@ -33,7 +39,47 @@ module ActiveFedora | |
| 33 39 | 
             
                  #   Account.reflections
         | 
| 34 40 | 
             
                  #
         | 
| 35 41 | 
             
                  def reflections
         | 
| 36 | 
            -
                     | 
| 42 | 
            +
                    @__reflections ||= begin
         | 
| 43 | 
            +
                      ref = {}
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      _reflections.each do |name, reflection|
         | 
| 46 | 
            +
                        parent_reflection = reflection.parent_reflection
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                        if parent_reflection
         | 
| 49 | 
            +
                          parent_name = parent_reflection.name
         | 
| 50 | 
            +
                          ref[parent_name.to_s] = parent_reflection
         | 
| 51 | 
            +
                        else
         | 
| 52 | 
            +
                          ref[name] = reflection
         | 
| 53 | 
            +
                        end
         | 
| 54 | 
            +
                      end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                      ref
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  # Returns an array of AssociationReflection objects for all the
         | 
| 61 | 
            +
                  # associations in the class. If you only want to reflect on a certain
         | 
| 62 | 
            +
                  # association type, pass in the symbol (<tt>:has_many</tt>, <tt>:has_one</tt>,
         | 
| 63 | 
            +
                  # <tt>:belongs_to</tt>) as the first parameter.
         | 
| 64 | 
            +
                  #
         | 
| 65 | 
            +
                  # Example:
         | 
| 66 | 
            +
                  #
         | 
| 67 | 
            +
                  #   Account.reflect_on_all_associations             # returns an array of all associations
         | 
| 68 | 
            +
                  #   Account.reflect_on_all_associations(:has_many)  # returns an array of all has_many associations
         | 
| 69 | 
            +
                  #
         | 
| 70 | 
            +
                  def reflect_on_all_associations(macro = nil)
         | 
| 71 | 
            +
                    association_reflections = reflections.dup
         | 
| 72 | 
            +
                    association_reflections.select! { |_k, reflection| reflection.macro == macro } if macro
         | 
| 73 | 
            +
                    association_reflections
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  # Returns the AssociationReflection object for the +association+ (use the symbol).
         | 
| 77 | 
            +
                  #
         | 
| 78 | 
            +
                  #   Account.reflect_on_association(:owner)             # returns the owner AssociationReflection
         | 
| 79 | 
            +
                  #   Invoice.reflect_on_association(:line_items).macro  # returns :has_many
         | 
| 80 | 
            +
                  #
         | 
| 81 | 
            +
                  def reflect_on_association(association)
         | 
| 82 | 
            +
                    __reflect_on_association(association)
         | 
| 37 83 | 
             
                  end
         | 
| 38 84 |  | 
| 39 85 | 
             
                  def outgoing_reflections
         | 
| @@ -41,11 +87,11 @@ module ActiveFedora | |
| 41 87 | 
             
                  end
         | 
| 42 88 |  | 
| 43 89 | 
             
                  def child_resource_reflections
         | 
| 44 | 
            -
                     | 
| 90 | 
            +
                    reflect_on_all_associations(:contains).select { |_, reflection| reflection.klass <= ActiveFedora::File }
         | 
| 45 91 | 
             
                  end
         | 
| 46 92 |  | 
| 47 93 | 
             
                  def contained_rdf_source_reflections
         | 
| 48 | 
            -
                     | 
| 94 | 
            +
                    reflect_on_all_associations(:contains).select { |_, reflection| !(reflection.klass <= ActiveFedora::File) }
         | 
| 49 95 | 
             
                  end
         | 
| 50 96 |  | 
| 51 97 | 
             
                  # Returns the AssociationReflection object for the +association+ (use the symbol).
         | 
| @@ -66,14 +112,79 @@ module ActiveFedora | |
| 66 112 | 
             
                  def reflect_on_all_autosave_associations
         | 
| 67 113 | 
             
                    reflections.values.select { |reflection| reflection.options[:autosave] }
         | 
| 68 114 | 
             
                  end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                  def clear_reflections_cache # :nodoc:
         | 
| 117 | 
            +
                    @__reflections = nil
         | 
| 118 | 
            +
                  end
         | 
| 69 119 | 
             
                end
         | 
| 70 120 |  | 
| 71 | 
            -
                 | 
| 121 | 
            +
                # Holds all the methods that are shared between MacroReflection and ThroughReflection.
         | 
| 122 | 
            +
                #
         | 
| 123 | 
            +
                #   AbstractReflection
         | 
| 124 | 
            +
                #     MacroReflection
         | 
| 125 | 
            +
                #       AggregateReflection
         | 
| 126 | 
            +
                #       AssociationReflection
         | 
| 127 | 
            +
                #         HasManyReflection
         | 
| 128 | 
            +
                #         HasOneReflection
         | 
| 129 | 
            +
                #         BelongsToReflection
         | 
| 130 | 
            +
                #         HasAndBelongsToManyReflection
         | 
| 131 | 
            +
                #     ThroughReflection
         | 
| 132 | 
            +
                #       PolymorphicReflection
         | 
| 133 | 
            +
                #         RuntimeReflection
         | 
| 134 | 
            +
                class AbstractReflection # :nodoc:
         | 
| 135 | 
            +
                  def through_reflection?
         | 
| 136 | 
            +
                    false
         | 
| 137 | 
            +
                  end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                  # Returns a new, unsaved instance of the associated class. +attributes+ will
         | 
| 140 | 
            +
                  # be passed to the class's constructor.
         | 
| 141 | 
            +
                  def build_association(attributes, &block)
         | 
| 142 | 
            +
                    klass.new(attributes, &block)
         | 
| 143 | 
            +
                  end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                  # Returns the class name for the macro.
         | 
| 146 | 
            +
                  #
         | 
| 147 | 
            +
                  # <tt>composed_of :balance, class_name: 'Money'</tt> returns <tt>'Money'</tt>
         | 
| 148 | 
            +
                  # <tt>has_many :clients</tt> returns <tt>'Client'</tt>
         | 
| 149 | 
            +
                  def class_name
         | 
| 150 | 
            +
                    @class_name ||= (options[:class_name] || derive_class_name).to_s
         | 
| 151 | 
            +
                  end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  def constraints
         | 
| 154 | 
            +
                    scope_chain.flatten
         | 
| 155 | 
            +
                  end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                  def inverse_of
         | 
| 158 | 
            +
                    return unless inverse_name
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                    @inverse_of ||= klass._reflect_on_association inverse_name
         | 
| 161 | 
            +
                  end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                  def check_validity_of_inverse!
         | 
| 164 | 
            +
                    unless polymorphic?
         | 
| 165 | 
            +
                      if has_inverse? && inverse_of.nil?
         | 
| 166 | 
            +
                        raise InverseOfAssociationNotFoundError, self
         | 
| 167 | 
            +
                      end
         | 
| 168 | 
            +
                    end
         | 
| 169 | 
            +
                  end
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                  def alias_candidate(name)
         | 
| 172 | 
            +
                    "#{plural_name}_#{name}"
         | 
| 173 | 
            +
                  end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                  def chain
         | 
| 176 | 
            +
                    collect_join_chain
         | 
| 177 | 
            +
                  end
         | 
| 178 | 
            +
                end
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                class MacroReflection < AbstractReflection
         | 
| 72 181 | 
             
                  # Returns the name of the macro.
         | 
| 73 182 | 
             
                  #
         | 
| 74 183 | 
             
                  # <tt>has_many :clients</tt> returns <tt>:clients</tt>
         | 
| 75 184 | 
             
                  attr_reader :name
         | 
| 76 185 |  | 
| 186 | 
            +
                  attr_reader :scope
         | 
| 187 | 
            +
             | 
| 77 188 | 
             
                  # Returns the macro type.
         | 
| 78 189 | 
             
                  #
         | 
| 79 190 | 
             
                  # <tt>has_many :clients</tt> returns <tt>:has_many</tt>
         | 
| @@ -86,27 +197,13 @@ module ActiveFedora | |
| 86 197 |  | 
| 87 198 | 
             
                  attr_reader :active_fedora
         | 
| 88 199 |  | 
| 89 | 
            -
                   | 
| 90 | 
            -
                  #
         | 
| 91 | 
            -
                  #   class Author < ActiveRecord::Base
         | 
| 92 | 
            -
                  #     has_many :books
         | 
| 93 | 
            -
                  #   end
         | 
| 94 | 
            -
                  #
         | 
| 95 | 
            -
                  #   Author._reflect_on_association(:books).klass
         | 
| 96 | 
            -
                  #   # => Book
         | 
| 97 | 
            -
                  #
         | 
| 98 | 
            -
                  # <b>Note:</b> Do not call +klass.new+ or +klass.create+ to instantiate
         | 
| 99 | 
            -
                  # a new association object. Use +build_association+ or +create_association+
         | 
| 100 | 
            -
                  # instead. This allows plugins to hook into association object creation.
         | 
| 101 | 
            -
                  def klass
         | 
| 102 | 
            -
                    @klass ||= class_name.constantize
         | 
| 103 | 
            -
                  end
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                  def initialize(macro, name, options, active_fedora)
         | 
| 200 | 
            +
                  def initialize(macro, name, scope, options, active_fedora)
         | 
| 106 201 | 
             
                    @macro = macro
         | 
| 107 202 | 
             
                    @name = name
         | 
| 203 | 
            +
                    @scope = scope
         | 
| 108 204 | 
             
                    @options = options
         | 
| 109 205 | 
             
                    @active_fedora = active_fedora
         | 
| 206 | 
            +
                    @klass         = options[:anonymous_class]
         | 
| 110 207 | 
             
                    @automatic_inverse_of = nil
         | 
| 111 208 | 
             
                  end
         | 
| 112 209 |  | 
| @@ -116,37 +213,26 @@ module ActiveFedora | |
| 116 213 | 
             
                    parent_reflection.autosave = autosave if parent_reflection
         | 
| 117 214 | 
             
                  end
         | 
| 118 215 |  | 
| 119 | 
            -
                  # Returns  | 
| 120 | 
            -
                  # be passed to the class's constructor.
         | 
| 121 | 
            -
                  def build_association(*options, &block)
         | 
| 122 | 
            -
                    klass.new(*options, &block)
         | 
| 123 | 
            -
                  end
         | 
| 124 | 
            -
             | 
| 125 | 
            -
                  # Returns the class name for the macro.
         | 
| 216 | 
            +
                  # Returns the class for the macro.
         | 
| 126 217 | 
             
                  #
         | 
| 127 | 
            -
                  # <tt> | 
| 128 | 
            -
                   | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
                  # Returns whether or not this association reflection is for a collection
         | 
| 133 | 
            -
                  # association. Returns +true+ if the +macro+ is either +has_many+ or
         | 
| 134 | 
            -
                  # +has_and_belongs_to_many+, +false+ otherwise.
         | 
| 135 | 
            -
                  def collection?
         | 
| 136 | 
            -
                    @collection
         | 
| 137 | 
            -
                  end
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                  # Returns +true+ if +self+ is a +belongs_to+ reflection.
         | 
| 140 | 
            -
                  def belongs_to?
         | 
| 141 | 
            -
                    macro == :belongs_to
         | 
| 218 | 
            +
                  # <tt>composed_of :balance, class_name: 'Money'</tt> returns the Money class
         | 
| 219 | 
            +
                  # <tt>has_many :clients</tt> returns the Client class
         | 
| 220 | 
            +
                  def klass
         | 
| 221 | 
            +
                    @klass ||= compute_class(class_name)
         | 
| 142 222 | 
             
                  end
         | 
| 143 223 |  | 
| 144 | 
            -
                  def  | 
| 145 | 
            -
                     | 
| 224 | 
            +
                  def compute_class(name)
         | 
| 225 | 
            +
                    name.constantize
         | 
| 146 226 | 
             
                  end
         | 
| 147 227 |  | 
| 148 | 
            -
                   | 
| 149 | 
            -
             | 
| 228 | 
            +
                  # Returns +true+ if +self+ and +other_aggregation+ have the same +name+ attribute, +active_record+ attribute,
         | 
| 229 | 
            +
                  # and +other_aggregation+ has an options hash assigned to it.
         | 
| 230 | 
            +
                  def ==(other)
         | 
| 231 | 
            +
                    super ||
         | 
| 232 | 
            +
                      other.is_a?(self.class) &&
         | 
| 233 | 
            +
                        name == other.name &&
         | 
| 234 | 
            +
                        !other.options.nil? &&
         | 
| 235 | 
            +
                        active_record == other.active_record
         | 
| 150 236 | 
             
                  end
         | 
| 151 237 |  | 
| 152 238 | 
             
                  private
         | 
| @@ -156,22 +242,6 @@ module ActiveFedora | |
| 156 242 | 
             
                      class_name = class_name.singularize if collection?
         | 
| 157 243 | 
             
                      class_name
         | 
| 158 244 | 
             
                    end
         | 
| 159 | 
            -
             | 
| 160 | 
            -
                    def derive_foreign_key
         | 
| 161 | 
            -
                      if belongs_to?
         | 
| 162 | 
            -
                        "#{name}_id"
         | 
| 163 | 
            -
                      elsif has_and_belongs_to_many?
         | 
| 164 | 
            -
                        "#{name.to_s.singularize}_ids"
         | 
| 165 | 
            -
                      elsif options[:as]
         | 
| 166 | 
            -
                        "#{options[:as]}_id"
         | 
| 167 | 
            -
                      elsif inverse_of && inverse_of.collection?
         | 
| 168 | 
            -
                        # for a has_many that is the inverse of a has_and_belongs_to_many
         | 
| 169 | 
            -
                        "#{options[:inverse_of].to_s.singularize}_ids"
         | 
| 170 | 
            -
                      else
         | 
| 171 | 
            -
                        # for a has_many that is the inverse of a belongs_to
         | 
| 172 | 
            -
                        active_fedora.name.foreign_key
         | 
| 173 | 
            -
                      end
         | 
| 174 | 
            -
                    end
         | 
| 175 245 | 
             
                end
         | 
| 176 246 |  | 
| 177 247 | 
             
                # Holds all the meta-data about an association as it was specified in the
         | 
| @@ -179,9 +249,13 @@ module ActiveFedora | |
| 179 249 | 
             
                class AssociationReflection < MacroReflection #:nodoc:
         | 
| 180 250 | 
             
                  attr_accessor :parent_reflection # Reflection
         | 
| 181 251 |  | 
| 182 | 
            -
                  def initialize(macro, name, options, active_fedora)
         | 
| 252 | 
            +
                  def initialize(macro, name, scope, options, active_fedora)
         | 
| 183 253 | 
             
                    super
         | 
| 184 | 
            -
                    @ | 
| 254 | 
            +
                    @constructable = calculate_constructable(macro, options)
         | 
| 255 | 
            +
                  end
         | 
| 256 | 
            +
             | 
| 257 | 
            +
                  def constructable? # :nodoc:
         | 
| 258 | 
            +
                    @constructable
         | 
| 185 259 | 
             
                  end
         | 
| 186 260 |  | 
| 187 261 | 
             
                  # Creates a new instance of the associated class, and immediately saves it
         | 
| @@ -221,11 +295,17 @@ module ActiveFedora | |
| 221 295 |  | 
| 222 296 | 
             
                  # A chain of reflections from this one back to the owner. For more see the explanation in
         | 
| 223 297 | 
             
                  # ThroughReflection.
         | 
| 224 | 
            -
                  def  | 
| 298 | 
            +
                  def collect_join_chain
         | 
| 225 299 | 
             
                    [self]
         | 
| 226 300 | 
             
                  end
         | 
| 301 | 
            +
                  alias chain collect_join_chain # todo
         | 
| 227 302 |  | 
| 228 | 
            -
                   | 
| 303 | 
            +
                  # Returns whether or not this association reflection is for a collection
         | 
| 304 | 
            +
                  # association. Returns +true+ if the +macro+ is either +has_many+ or
         | 
| 305 | 
            +
                  # +has_and_belongs_to_many+, +false+ otherwise.
         | 
| 306 | 
            +
                  def collection?
         | 
| 307 | 
            +
                    [:has_many, :has_and_belongs_to_many, :directly_contains, :indirectly_contains].include?(macro)
         | 
| 308 | 
            +
                  end
         | 
| 229 309 |  | 
| 230 310 | 
             
                  def has_inverse?
         | 
| 231 311 | 
             
                    inverse_name
         | 
| @@ -276,8 +356,25 @@ module ActiveFedora | |
| 276 356 | 
             
                  VALID_AUTOMATIC_INVERSE_MACROS = [:has_many, :has_and_belongs_to_many, :belongs_to].freeze
         | 
| 277 357 | 
             
                  INVALID_AUTOMATIC_INVERSE_OPTIONS = [:conditions, :through, :polymorphic, :foreign_key].freeze
         | 
| 278 358 |  | 
| 359 | 
            +
                  # Returns +true+ if +self+ is a +belongs_to+ reflection.
         | 
| 360 | 
            +
                  def belongs_to?
         | 
| 361 | 
            +
                    macro == :belongs_to
         | 
| 362 | 
            +
                  end
         | 
| 363 | 
            +
             | 
| 364 | 
            +
                  def has_many?
         | 
| 365 | 
            +
                    macro == :has_many
         | 
| 366 | 
            +
                  end
         | 
| 367 | 
            +
             | 
| 368 | 
            +
                  def has_and_belongs_to_many?
         | 
| 369 | 
            +
                    macro == :has_and_belongs_to_many
         | 
| 370 | 
            +
                  end
         | 
| 371 | 
            +
             | 
| 279 372 | 
             
                  private
         | 
| 280 373 |  | 
| 374 | 
            +
                    def calculate_constructable(_macro, _options)
         | 
| 375 | 
            +
                      true
         | 
| 376 | 
            +
                    end
         | 
| 377 | 
            +
             | 
| 281 378 | 
             
                    def inverse_name
         | 
| 282 379 | 
             
                      options.fetch(:inverse_of) do
         | 
| 283 380 | 
             
                        if @automatic_inverse_of == false
         | 
| @@ -336,9 +433,30 @@ module ActiveFedora | |
| 336 433 | 
             
                        !INVALID_AUTOMATIC_INVERSE_OPTIONS.any? { |opt| reflection.options[opt] }
         | 
| 337 434 | 
             
                      # && !reflection.scope
         | 
| 338 435 | 
             
                    end
         | 
| 436 | 
            +
             | 
| 437 | 
            +
                    def derive_foreign_key
         | 
| 438 | 
            +
                      if belongs_to?
         | 
| 439 | 
            +
                        "#{name}_id"
         | 
| 440 | 
            +
                      elsif has_and_belongs_to_many?
         | 
| 441 | 
            +
                        "#{name.to_s.singularize}_ids"
         | 
| 442 | 
            +
                      elsif options[:as]
         | 
| 443 | 
            +
                        "#{options[:as]}_id"
         | 
| 444 | 
            +
                      elsif inverse_of && inverse_of.collection?
         | 
| 445 | 
            +
                        # for a has_many that is the inverse of a has_and_belongs_to_many
         | 
| 446 | 
            +
                        "#{options[:inverse_of].to_s.singularize}_ids"
         | 
| 447 | 
            +
                      else
         | 
| 448 | 
            +
                        # for a has_many that is the inverse of a belongs_to
         | 
| 449 | 
            +
                        active_fedora.name.foreign_key
         | 
| 450 | 
            +
                      end
         | 
| 451 | 
            +
                    end
         | 
| 339 452 | 
             
                end
         | 
| 340 453 |  | 
| 341 454 | 
             
                class RDFPropertyReflection < AssociationReflection
         | 
| 455 | 
            +
                  def initialize(*args)
         | 
| 456 | 
            +
                    super
         | 
| 457 | 
            +
                    active_fedora.index_config[name] = build_index_config
         | 
| 458 | 
            +
                  end
         | 
| 459 | 
            +
             | 
| 342 460 | 
             
                  def derive_foreign_key
         | 
| 343 461 | 
             
                    name
         | 
| 344 462 | 
             
                  end
         | 
| @@ -348,6 +466,12 @@ module ActiveFedora | |
| 348 466 | 
             
                    class_name = class_name.singularize if collection?
         | 
| 349 467 | 
             
                    class_name
         | 
| 350 468 | 
             
                  end
         | 
| 469 | 
            +
             | 
| 470 | 
            +
                  private
         | 
| 471 | 
            +
             | 
| 472 | 
            +
                    def build_index_config
         | 
| 473 | 
            +
                      ActiveFedora::Indexing::Map::IndexObject.new(predicate_for_solr) { |index| index.as :symbol }
         | 
| 474 | 
            +
                    end
         | 
| 351 475 | 
             
                end
         | 
| 352 476 | 
             
              end
         | 
| 353 477 | 
             
            end
         |