I have a model called a voip_phone that has a an attribute schedule which is a string that keeps track of which people are using the phone at what time. Here’s an example of a schedule:
"mon{}sun{}sat{}tue{13,08:45,15:15;}wed{13,09:00,17:30;}thu{}fri{}"
Here is the model code that won’t work:
def add_shift(days, person_id, time_from, time_to)
return false if shift_overlap?(days, time_from, time_to)
days.each do |d|
insert_point = self.schedule.index(d)+4
self.schedule.insert(
insert_point, [person_id.to_s, time_from, time_to].join(",") + ";")
end
save!
end
No matter what I do, I can’t get this method to work. Here’s a readout from the console:
v = VoipPhone.find(5)
=> blah, blah, blah
v.add_shift(["thu", "fri"], 13, "08:45", "15:15")
=> true
This seems to work, but the changes don’t stick. Calling v.schedule shows the new schedule, but calling VoipPhone.find(5).schedule still shows the old schedule. Calling v.save returns true, but the changes still won’t stick!
Any help that could be offered to a karmaless soul would be greatly appreciated 🙂
You’re facing a “dirty attributes” optimization that was introduced in Rails 2.3 AFAIR
See this article
in short, call “self.schedule_will_change!” before actually changing it.
If it will not work for you, then you can workaround with ‘dup’ like: