Skip to content

Instantly share code, notes, and snippets.

@regedarek
Forked from krisleech/00_value_object.rb
Created May 8, 2014 08:32
Show Gist options
  • Save regedarek/d3a13d41e92a57b58985 to your computer and use it in GitHub Desktop.
Save regedarek/d3a13d41e92a57b58985 to your computer and use it in GitHub Desktop.
class Leg
include ActiveModel::Validations
include ActiveModel::Naming
include ActiveModel::Conversion
include Virtus
attribute :start_day, Integer
attribute :end_day, Integer
end
# without Rails `serialize` macro, using our own getters/setters and serializeation
validate { legs.all?(&:valid?) }
# set default for column
after_initialize do
write_attribute(:legs, JSON.dump([])) if read_attribute(:legs).blank?
end
# getter
def legs
@legs ||= JSON.parse(read_attribute(:legs)).map { |attrs| Leg.new(attrs) }
end
# setter
def legs=(_legs)
@legs = _legs
end
# setter
# @presenter
def legs_attributes=(legs_attributes)
self.legs = legs_attributes.map { |attrs| Leg.new(attrs) }
write_attribute(:legs, JSON.dump(@legs))
end
# using Rails `serialize` macro.
validate { legs.valid? }
serialize :legs, Legs
# Legs acts as a serializer for an array of Leg objects
class Legs
include ActiveModel::Validations
include ActiveModel::Naming
include ActiveModel::Conversion
include Virtus
attribute :legs, Array[Leg]
validate :legs_valid
def initialize(legs_attributes = [])
super(:legs => legs_attributes)
end
# delegate everything to the Array, so we don't have to do model.legs.legs.each
def method_missing(method_name, *args, &block)
legs.send(method_name, *args, &block) if legs.respond_to?(method_name)
end
private
def legs_valid
legs.all?(&:valid?)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment