Class: ActiveRecord::Associations::PolymorphicAssociation

Inherits:
HasManyThroughAssociation
  • Object
show all
Defined in:
lib/has_many_polymorphs/association.rb

Overview

The association class for a has_many_polymorphs association.

Instance Method Summary collapse

Instance Method Details

#<<(*records) ⇒ Object Also known as: push, concat

Push a record onto the association. Triggers a database load for a uniqueness check only if :skip_duplicates is true. Return value is undefined.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/has_many_polymorphs/association.rb', line 14

def <<(*records)
  return if records.empty?

  if @reflection.options[:skip_duplicates]
    _logger_debug "Loading instances for polymorphic duplicate push check; use :skip_duplicates => false and perhaps a database constraint to avoid this possible performance issue"
    load_target
  end
  
  @reflection.klass.transaction do
    flatten_deeper(records).each do |record|
      if @owner.new_record? or not record.respond_to?(:new_record?) or record.new_record?
        raise PolymorphicError, "You can't associate unsaved records."            
      end
      next if @reflection.options[:skip_duplicates] and @target.include? record
      @owner.send(@reflection.through_reflection.name).proxy_target << @reflection.klass.create!(construct_join_attributes(record))
      @target << record if loaded?
    end
  end
  
  self
end

#clear(klass = nil) ⇒ Object

Clears all records from the association. Returns an empty array.



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/has_many_polymorphs/association.rb', line 70

def clear(klass = nil)
  load_target
  return if @target.empty?
  
  if klass
    delete(@target.select {|r| r.is_a? klass })
  else
    @owner.send(@reflection.through_reflection.name).clear
    @target.clear
  end
  []
end

#construct_scopeObject



46
47
48
49
# File 'lib/has_many_polymorphs/association.rb', line 46

def construct_scope
  _logger_warn "Warning; not all usage scenarios for polymorphic scopes are supported yet."
  super
end

#delete(*records) ⇒ Object

Deletes a record from the association. Return value is undefined.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/has_many_polymorphs/association.rb', line 52

def delete(*records)
  records = flatten_deeper(records)
  records.reject! {|record| @target.delete(record) if record.new_record?}
  return if records.empty?
  
  @reflection.klass.transaction do
    records.each do |record|
      joins = @reflection.through_reflection.name
      @owner.send(joins).delete(@owner.send(joins).select do |join|
        join.send(@reflection.options[:polymorphic_key]) == record.id and 
        join.send(@reflection.options[:polymorphic_type_key]) == "#{record.class.base_class}"
      end)
      @target.delete(record)
    end
  end
end

#find(*args) ⇒ Object

Runs a find against the association contents, returning the matched records. All regular find options except :include are supported.



40
41
42
43
44
# File 'lib/has_many_polymorphs/association.rb', line 40

def find(*args)
  opts = args._extract_options!
  opts.delete :include
  super(*(args + [opts]))
end