Polymorphism/Polymorphic Associations
Polymorphism / Polymorphic Associations
Polymorphism
Polymorphism = Send the same message to different objects and get different results.
Inheritance
class GenericParser
def parse
raise NotImplementedError, 'No method'
end
end
# inheritance 1
class JsonParser < GenericParser
def parse
puts 'JsonParser instance received a message.'
end
end
# inheritance 2
class XmlParser < GenericParser
def parse
puts 'XmlParser instance received a message.'
end
end
puts 'Using the XmlParser'
xml_parser = XmlParser.new
xml_parser.parse
puts 'Using the JsonParser'
json_parser = JsonParser.new
json_parser.parse
# Using the XmlParser
# XmlParser instance received a message.
# Using the JsonParser
# JsonParser instance received a message.
Duck Typing
class XmlParser
def parse
puts 'XmlParser!!!'
end
end
class JsonParser
def parse
puts 'JsonParser!!!'
end
end
class GenericParser
def parse(parser)
parser.parse
end
end
gene_parser = GenericParser.new
puts 'Using the XmlParser'
gene_parser.parse(XmlParser.new)
puts 'Using the JsonParser'
gene_parser.parse(JsonParser.new)
# Using the XmlParser
# XmlParser!!!
# Using the JsonParser
# JsonParser!!!
Decorator
class Parser
def parse
puts 'Parser!!!'
end
end
class XmlParser
def initialize(parser)
@parser = parser
end
def parse
puts 'XmlParser'
@parser.parse
end
end
class JsonParser
def initialize(parser)
@parser = parser
end
def parse
puts 'JsonParser'
@parser.parse
end
end
puts 'Using the XmlParser'
parser = Parser.new
XmlParser.new(parser).parse
puts 'Using the JsonParser'
JsonParser.new(parser).parse
puts 'Using both Parsers!'
JsonParser.new(XmlParser.new(parser)).parse
# Using the XmlParser
# XmlParser
# Parser!!!
# Using the JsonParser
# JsonParser
# Parser!!!
# Using both Parsers!
# JsonParser
# XmlParser
# Parser!!!
Polymorphic Associations
A model can belong to more than one other model, on a single association.
class Picture < ApplicationRecord
belongs_to :imageable, polymorphic: true
end
class Employee < ApplicationRecord
has_many :pictures, as: :imageable
end
class Product < ApplicationRecord
has_many :pictures, as: :imageable
end
# @employee.pictures.
# @product.pictures.
class CreatePictures < ActiveRecord::Migration[5.0]
def change
create_table :pictures do |t|
t.string :name
t.integer :imageable_id
t.string :imageable_type
t.timestamps
end
add_index :pictures, [:imageable_type, :imageable_id]
end
end
Last updated
Was this helpful?