I found this article: Override a Mongoid model's setters and getters to help me, but behavior's still not what I am looking for.
My model is like so:
class Event
include Mongoid::Document
include IceCube
validates_presence_of :title
field :title, type: String
field :description, type: String
field :schedule, type: Hash
attr_protected :schedule_hash
def schedule=(new_schedule)
super(new_schedule.to_hash)
end
def schedule
Schedule.from_hash(super())
end
end
This works more or less as I'd expect, in that it serializes and deserializes the IceCube object, but what I noticed is that while I can do this:
s = Schedule.new(Time.now)
s.add_recurrence_rule Rule.daily
e = Event.new
e.schedule = s
it seems to serialize and deseralize as I would expect, and I can call things like
e.schedule.occurs_at?(Date.today + 1.day)
and get the expected response. However, if I try:
e.schedule.add_recurrence_rule Rule.daily
instead of calling it on the local variable s
before setting the property on event
, I can look at the hash and see the rule is not persisted.
Is there something I'm missing on the right way of doing this sort of thing in Ruby or Mongoid?
I tried using write_attribute and read_attribute, but that was likewise to no avail.
While not the most pretty, this strategy will work:
class Event
include Mongoid::Document
validates_presence_of :title
field :title, type: String
field :description, type: String
field :schedule
before_save do
write_attribute(:schedule, @schedule.to_yaml)
end
def schedule=(s)
@schedule = s
end
def schedule
@schedule ||= begin
yaml = read_attribute(:schedule)
yaml ? IceCube::Schedule.from_yaml(yaml) : IceCube::Schedule.new
end
end
end