def has_many(association_name, metadata={})

      add_association association_name, :has_many, metadata

      association_class_name = metadata.try(:fetch, :class_name, [name.split('::')[0..-2].join('::'), association_name.to_s.classify].reject(&:blank?).join('::'))

      # foos
      define_method(association_name) do |*query|
        association_class = association_class_name.constantize

        # TODO: Support a more generic version of lazy-loading
        if query.empty? # Ex: Books.all, so we want to cache it.
          ivar = "@#{association_name}"
          if instance_variable_defined?(ivar)
            instance_variable_get(ivar)
          elsif self.class.autoload_associations? && association_class.respond_to?(:all)
            instance_variable_set(ivar, Array(association_class.all("#{self.class.name.underscore}_id" => id)))
          else
            []
          end
        else # Ex: Book.all(:name => "The..."), so we do not want to cache it
          if self.class.autoload_associations? && association_class.respond_to?(:all)
            Array(association_class.all({"#{self.class.name.demodulize.underscore}_id" => id}.merge(query.first)))
          end
        end
      end

      # foos=
      define_method("#{association_name}=") do |arg|
        association_class = association_class_name.constantize

        attr_name = self.class.name.demodulize.underscore
        objs = (arg.is_a?(Hash) ? arg.values : Array(arg)).map do |obj|
          o = association_class.cast(obj)

          if o.respond_to?("#{attr_name}=")
            o.send("#{attr_name}=", self)
          end

          if o.respond_to?("#{attr_name}_id=") && respond_to?(:id)
            o.send("#{attr_name}_id=", id)
          end

          o
        end
        instance_variable_set("@#{association_name}", objs)
      end
    end
def has_many(association_name, metadata={})

      add_association association_name, :has_many, metadata

      association_class_name = metadata.try(:fetch, :class_name, [name.split('::')[0..-2].join('::'), association_name.to_s.classify].reject(&:blank?).join('::'))

      # foos
      define_method(association_name) do |*query|
        association_class = association_class_name.constantize

        # TODO: Support a more generic version of lazy-loading
        if query.empty? # Ex: Books.all, so we want to cache it.
          ivar = "@#{association_name}"
          if instance_variable_defined?(ivar)
            instance_variable_get(ivar)
          elsif self.class.autoload_associations? && association_class.respond_to?(:all)
            instance_variable_set(ivar, Array(association_class.all("#{self.class.name.underscore}_id" => id)))
          else
            []
          end
        else # Ex: Book.all(:name => "The..."), so we do not want to cache it
          if self.class.autoload_associations? && association_class.respond_to?(:all)
            Array(association_class.all({"#{self.class.name.demodulize.underscore}_id" => id}.merge(query.first)))
          end
        end
      end

      # foos=
      define_method("#{association_name}=") do |arg|
        association_class = association_class_name.constantize

        attr_name = self.class.name.demodulize.underscore
        objs = (arg.is_a?(Hash) ? arg.values : Array(arg)).map do |obj|
          o = association_class.cast(obj)

          if o.respond_to?("#{attr_name}=")
            o.send("#{attr_name}=", self)
          end

          if o.respond_to?("#{attr_name}_id=") && respond_to?(:id)
            o.send("#{attr_name}_id=", id)
          end

          o
        end
        instance_variable_set("@#{association_name}", objs)
      end
    end
Defines an association that is a reference to an Array of another Attribution class.

 @param [Symbol] association_name The name of the association
 @param [Hash] metadata Extra information about the association.
 @option metadata [String] :class_name Class of the association,
   defaults to a class name based on the association name