Created
February 21, 2015 11:03
-
-
Save berkes/2e5cc1eca716f6faddfb to your computer and use it in GitHub Desktop.
Ruby Metaprogramming to create a duck-type converter. Example is a converter that allows me to convert a Product Duck Type into a self (LineItem).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Spree | |
module Piwik | |
class LineItem | |
include ActiveModel::Model | |
ATTRIBUTES = [:sku, :name, :price, :quantity, :categories] | |
attr_accessor(*ATTRIBUTES) | |
## | |
# Create a LineItem from a Spree::LinteItem-ish thing (line_items, | |
# products, variants) | |
# | |
# All attributes in ATTRIBUTES will be mapped: | |
# | |
# When we add a (private) method with the name | |
# map_product_ish_sku, this method will be called and get the | |
# product_ish to generate a value for that attribute. | |
# | |
# When the product_ish has the same attribute name and no | |
# mapping-method provided the value, it will simply use the value | |
# from that attribute on product_ish | |
def self.from_product_ish(product_ish) | |
values = ATTRIBUTES.map { |a| [a, product_ish_attr(a, product_ish)] } | |
new(Hash[values]) | |
end | |
private | |
def self.product_ish_attr(attr_name, product_ish) | |
mapping_method = "map_product_ish_#{attr_name}".to_sym | |
self.respond_to?(mapping_method) ? send(mapping_method, product_ish) : product_ish.try(attr_name) | |
end | |
def self.map_product_ish_categories(product_ish) | |
defaulted_taxons = product_ish.try(:taxons) || [] | |
defaulted_taxons.map(&:name).first(5) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment