Seeing that the @values instance variable is heavily used elsewhere in
the code, we have to change the implementation to leave @values alone.

Here is a proposal that will benefit in fixing the documented
shortcomings (it will not benefit in detecting an internal
modification of an attribute value using a ! method):

class Model

  # allows user to see original values
  def saved_values
    @saved_values ||= {}
  end

  def []=(column, value)
    new_value = typecast_value(column, value)
    if @values[column] != new_value
      @saved_values[column] = @values[column] unless
saved_values.include?(column)
      @values[column] = new_value
    end
  end

  def changed_columns
    saved_values.keys.find_all {|c| @values[c] != @saved_values[c]}
  end

  # allows user to see changes indexed by column name
  def changes
    ret = {}
    changed_columns.each {|c| ret[c] = [...@saved_values[c], @values[c]]}
  end

end

With this approach, the only performance cost is in #changed_columns,
and it's not that big of a cost.
The only other downside is that the internal modification of a value
problem is magnified here:

# Problematic both before and after new implementation
x = Model.new(:name => 'david')
x.name.gsub! 'david', 'dave'
x.save #=> no change
x.name = 'dave'
x.save #=> no change

# Problematic only in new implementation
x.name = x.name.gsub!('david', 'dave')
x.save #=> no change, but would have changed in previous implementation
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/sequel-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to