Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save CoralineAda/ca90eafbabb2ba3c48092abc3783de63 to your computer and use it in GitHub Desktop.
Save CoralineAda/ca90eafbabb2ba3c48092abc3783de63 to your computer and use it in GitHub Desktop.
# config/initializers/attribute_types.rb
ActiveRecord::Type.register(:discount_line_type, DiscountLineType)
# discount_line_type.rb
class DiscountLineType < ActiveRecord::Type::Value
DISCOUNT_LINE = Struct.new(:name, :description, :amount, keyword_init: true)
def type
:jsonb
end
def cast(value)
decoded = ActiveSupport::JSON.decode(value)
decoded.map do |obj|
obj["amount"] = amount_to_money(obj["amount"])
DISCOUNT_LINE.new(obj)
end
end
def amount_to_money(amount_hash={})
value_cents = amount_hash['value'].to_s.to_f * 100
return Money.new(value_cents, amount_hash['currency'])
end
end
# order.rb
class Order < ApplicationRecord
# discount_lines is stored in the database as a jsonb column
attribute :discount_lines, :discount_line_type, array: true
end
# Usage
> o = Order.last
> o.discount_lines
=>
[#<struct Order::DiscountLineType::DISCOUNT_LINE
description="Big sale",
name=nil,
amount=#<Money fractional:100 currency:USD>>]
> o.discount_lines.first.description
=> "Big sale"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment