customer.rb 2.1 KB
Newer Older
D
Initial  
David Heinemeier Hansson 已提交
1
class Customer < ActiveRecord::Base
2
  cattr_accessor :gps_conversion_was_run
3 4

  composed_of :address, :mapping => [ %w(address_street street), %w(address_city city), %w(address_country country) ], :allow_nil => true
5
  composed_of :balance, :class_name => "Money", :mapping => %w(balance amount), :converter => Proc.new(&:to_money)
6 7 8 9
  composed_of :gps_location, :allow_nil => true
  composed_of :non_blank_gps_location, :class_name => "GpsLocation", :allow_nil => true, :mapping => %w(gps_location gps_location),
              :converter => lambda { |gps| self.gps_conversion_was_run = true; gps.blank? ? nil : GpsLocation.new(gps)}
  composed_of :fullname, :mapping => %w(name to_s), :constructor => Proc.new { |name| Fullname.parse(name) }, :converter => :parse
D
Initial  
David Heinemeier Hansson 已提交
10 11 12 13 14 15 16 17
end

class Address
  attr_reader :street, :city, :country

  def initialize(street, city, country)
    @street, @city, @country = street, city, country
  end
J
Jeremy Kemper 已提交
18

D
Initial  
David Heinemeier Hansson 已提交
19 20 21
  def close_to?(other_address)
    city == other_address.city && country == other_address.country
  end
22 23 24

  def ==(other)
    other.is_a?(self.class) && other.street == street && other.city == city && other.country == country
J
Jeremy Kemper 已提交
25
  end
D
Initial  
David Heinemeier Hansson 已提交
26 27 28 29
end

class Money
  attr_reader :amount, :currency
J
Jeremy Kemper 已提交
30

D
Initial  
David Heinemeier Hansson 已提交
31
  EXCHANGE_RATES = { "USD_TO_DKK" => 6, "DKK_TO_USD" => 0.6 }
J
Jeremy Kemper 已提交
32

D
Initial  
David Heinemeier Hansson 已提交
33 34 35
  def initialize(amount, currency = "USD")
    @amount, @currency = amount, currency
  end
J
Jeremy Kemper 已提交
36

D
Initial  
David Heinemeier Hansson 已提交
37 38 39
  def exchange_to(other_currency)
    Money.new((amount * EXCHANGE_RATES["#{currency}_TO_#{other_currency}"]).floor, other_currency)
  end
40 41 42 43
end

class GpsLocation
  attr_reader :gps_location
J
Jeremy Kemper 已提交
44

45 46 47
  def initialize(gps_location)
    @gps_location = gps_location
  end
J
Jeremy Kemper 已提交
48

49 50 51
  def latitude
    gps_location.split("x").first
  end
J
Jeremy Kemper 已提交
52

53 54 55
  def longitude
    gps_location.split("x").last
  end
56 57 58 59

  def ==(other)
    self.latitude == other.latitude && self.longitude == other.longitude
  end
60
end
61 62 63 64 65 66

class Fullname
  attr_reader :first, :last

  def self.parse(str)
    return nil unless str
67 68 69 70 71 72

    if str.is_a?(Hash)
      new(str[:first], str[:last])
    else
      new(*str.to_s.split)
    end
73 74 75 76 77 78 79 80 81
  end

  def initialize(first, last = nil)
    @first, @last = first, last
  end

  def to_s
    "#{first} #{last.upcase}"
  end
82
end