Module: Traits::Association::Polymorphism

Included in:
Traits::Association
Defined in:
lib/traits/association/polymorphism.rb

Instance Method Summary collapse

Instance Method Details

#accepted_classes_through_polymorphismObject

Example 1:

class Picture
  belongs_to :imageable, polymorphic: true

class Toy
  has_one :picture, as: :imageable

picture_traits.associations[:imageable].accepted_classes_through_polymorphism
  => [Toy]

toy_traits.associations[:picture].accepted_classes_through_polymorphism
  => nil

Example 2:

class Picture
  belongs_to :imageable, polymorphic: true

class Present
  has_one :picture, as: :imageable

class Toy < Present
class VideoGame < Present
class Car < Present

picture_traits.associations[:imageable].accepted_classes_through_polymorphism
  => [Car, Present, Toy, VideoGame]

Note that items in list are sorted by class name



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

def accepted_classes_through_polymorphism
  if polymorphic?
    classes     = []
    attr_name   = attribute_name_for_polymorphic_type
    this_class  = from_active_record

    Traits.active_record_descendants.each do |active_record|
      # Skip current model and models which are STI derived
      next if active_record <= this_class # Means is or derived from current model

      active_record.traits.associations.each do |assoc|
        if assoc.attribute_name_for_polymorphic_type == attr_name
          classes << assoc.from_active_record
        end
      end
    end
    classes.uniq.sort! { |l, r| l.to_s <=> r.to_s  }
  end
end

#attribute_for_polymorphic_typeObject



101
102
103
104
105
106
107
# File 'lib/traits/association/polymorphism.rb', line 101

def attribute_for_polymorphic_type
  if polymorphic?
    from.attributes[attribute_for_polymorphic_type]
  elsif paired_through_polymorphism?
    to.attributes[reflection.foreign_type]
  end
end

#attribute_name_for_polymorphic_typeObject

class Picture

belongs_to :imageable, polymorphic: true

class Toy

has_one :picture, as: :imageable

picture_traits.associations.polymorphic_type_attribute_name => :imageable_type toy_traits.associations.polymorphic_type_attribute_name => :imageable_type



93
94
95
96
97
98
99
# File 'lib/traits/association/polymorphism.rb', line 93

def attribute_name_for_polymorphic_type
  if polymorphic?
    reflection.foreign_type.to_sym
  elsif paired_through_polymorphism?
    reflection.type.to_sym
  end
end

#paired_through_polymorphism?Boolean

class Picture

belongs_to :imageable, polymorphic: true

class Toy

has_one :picture, as: :imageable

picture_traits.associations.paired_through_polymorphism? => false toy_traits.associations.paired_through_polymorphism? => true

Returns:

  • (Boolean)


80
81
82
# File 'lib/traits/association/polymorphism.rb', line 80

def paired_through_polymorphism?
  reflection.type.present?
end

#polymorphic?Boolean Also known as: accepts_various_classes?

class Picture

belongs_to :imageable, polymorphic: true

class Toy

has_one :picture, as: :imageable

picture_traits.associations.polymorphic? => true toy_traits.associations.polymorphic? => false

Returns:

  • (Boolean)


16
17
18
# File 'lib/traits/association/polymorphism.rb', line 16

def polymorphic?
  belongs_to? && reflection.options[:polymorphic] == true
end

#to_hashObject



109
110
111
112
113
114
115
116
117
118
# File 'lib/traits/association/polymorphism.rb', line 109

def to_hash
  accepted_classes = accepted_classes_through_polymorphism
  super.merge!(
    polymorphic:                  polymorphic?,
    paired_through_polymorphism:  paired_through_polymorphism?,

    attribute_name_for_polymorphic_type:   attribute_name_for_polymorphic_type,
    accepted_classes_through_polymorphism: accepted_classes.try(:map) { |el| el.traits.name }
  )
end