module Hobo::Model::AccessibleAssociations

Public Instance Methods

find_by_name_or_id(finder, id_or_name) click to toggle source
# File lib/hobo/model/accessible_associations.rb, line 83
def find_by_name_or_id(finder, id_or_name)
  if id_or_name =~ /^@(.*)/
    id = $1
    finder.find(id)
  else
    finder.named(id_or_name)
  end
end
find_or_create_and_update(owner, association_name, finder, record_hash_or_string) { |id| ... } click to toggle source
# File lib/hobo/model/accessible_associations.rb, line 29
def find_or_create_and_update(owner, association_name, finder, record_hash_or_string)
  if record_hash_or_string.is_a?(String)
    return nil if record_hash_or_string.blank?

    # An ID or a name - the passed block will find the record
    record = find_by_name_or_id(finder, record_hash_or_string)

  elsif record_hash_or_string.is_a?(Hash)
    # A hash of attributes
    hash = record_hash_or_string

    # Remove completely blank hashes
    return nil if hash.values.all?(&:blank?)

    id = hash.delete(:id)

    record = yield id
    record.attributes = hash
    if owner.new_record? && record.new_record?
      # work around
      # https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/3510-has_many-build-does-not-set-reverse-reflection
      # https://hobo.lighthouseapp.com/projects/8324/tickets/447-validation-problems-with-has_many-accessible-true
      reverse = owner.class.reverse_reflection(association_name)
      if reverse && reverse.macro==:belongs_to
        method = "#{reverse.name}=".to_sym
        record.send(method, owner) if record.respond_to? method
      end
    else
      owner.include_in_save(association_name, record) unless owner.class.reflections[association_name.to_s].options[:through]
    end
  else
    # It's already a record
    record = record_hash_or_string
  end
  record
end
finder_for_belongs_to(record, name) click to toggle source
# File lib/hobo/model/accessible_associations.rb, line 92
def finder_for_belongs_to(record, name)
  refl = record.class.reflections[name.to_s]
  #conditions = ActiveRecord::Associations::BelongsToAssociation.new(record, refl).reflection.send(:conditions)
  conditions = [[]]
  conditions == [[]] || conditions == [[],[]] ? refl.klass : refl.klass.scoped(:conditions => conditions)
end
params_hash_to_array(array_or_hash) click to toggle source
# File lib/hobo/model/accessible_associations.rb, line 67
def params_hash_to_array(array_or_hash)
  if array_or_hash.is_a?(Hash)
    array = array_or_hash.get(*array_or_hash.keys.sort_by(&:to_i))
  elsif array_or_hash.is_a?(String)
    # Due to the way that rails works, there's no good way to tell
    # the difference between an empty array and a params hash that
    # just isn't making any updates to the array.  So we're
    # hacking this in: if you pass an empty string where an array
    # is expected, we assume you wanted an empty array.
    array_or_hash.split(',')
  else
    array_or_hash
  end
end
prepare_has_many_assignment(association, association_name, array_or_hash) click to toggle source
# File lib/hobo/model/accessible_associations.rb, line 7
def prepare_has_many_assignment(association, association_name, array_or_hash)
  owner = association.proxy_association.owner

  array = params_hash_to_array(array_or_hash)
  array.map! do |record_hash_or_string|
    finder = association.member_class
    conditions = association.proxy_association.reflection.options[:conditions]
    finder = finder.where(conditions) unless conditions == [[]] || conditions == [[],[]]
    find_or_create_and_update(owner, association_name, finder, record_hash_or_string) do |id|
      # The block is required to either locate find an existing record in the collection, or build a new one
      if id
        # TODO: We don't really want to find these one by one
        association.find(id)
      else
        association.build
      end
    end
  end
  array.compact
end