views:

21

answers:

1

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 :)

+1  A: 

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:

self.schedule = self.schedule.insert(....).dup
zed_0xff
Thanks, zed! self.schedule_will_change! did the trick perfectly!
muirbot