module Sequel::Plugins::Dirty::InstanceMethods

Attributes

previous_changes[R]

A hash of previous changes before the object was saved, in the same format as column_changes. Note that this is not necessarily the same as the columns that were used in the update statement.

Public Instance Methods

after_save() click to toggle source

Reset the initial values after saving.

Calls superclass method
# File lib/sequel/plugins/dirty.rb, line 73
def after_save
  super
  reset_initial_values
end
after_update() click to toggle source

Save the current changes so they are available after updating. This happens before #after_save resets them.

Calls superclass method
# File lib/sequel/plugins/dirty.rb, line 80
def after_update
  super
  @previous_changes = column_changes
end
column_change(column) click to toggle source

An array with the initial value and the current value of the column, if the column has been changed. If the column has not been changed, returns nil.

column_change(:name) # => ['Initial', 'Current']
# File lib/sequel/plugins/dirty.rb, line 90
def column_change(column)
  [initial_value(column), get_column_value(column)] if column_changed?(column)
end
column_changed?(column) click to toggle source

Either true or false depending on whether the column has changed. Note that this is not exactly the same as checking if the column is in changed_columns, if the column was not set initially.

column_changed?(:name) # => true
# File lib/sequel/plugins/dirty.rb, line 112
def column_changed?(column)
  initial_values.has_key?(column)
end
column_changes() click to toggle source

A hash with column symbol keys and pairs of initial and current values for all changed columns.

column_changes # => {:name => ['Initial', 'Current']}
# File lib/sequel/plugins/dirty.rb, line 98
def column_changes
  h = {}
  initial_values.each do |column, value|
    h[column] = [value, get_column_value(column)]
  end
  h
end
column_previously_changed?(column, opts=OPTS) click to toggle source

Whether the column was previously changed. Options:

:from

If given, the previous initial value of the column must match this

:to

If given, the previous changed value of the column must match this

update(name: 'Current')
previous_changes                  # => {:name=>['Initial', 'Current']}
column_previously_changed?(:name) # => true
column_previously_changed?(:id)   # => false
column_previously_changed?(:name, from: 'Initial', to: 'Current') # => true
column_previously_changed?(:name, from: 'Foo', to: 'Current')     # => false
# File lib/sequel/plugins/dirty.rb, line 127
def column_previously_changed?(column, opts=OPTS)
  return false unless (pc = @previous_changes) && (val = pc[column])

  if opts.has_key?(:from)
    return false unless val[0] == opts[:from]
  end

  if opts.has_key?(:to)
    return false unless val[1] == opts[:to]
  end

  true
end
column_previously_was(column) click to toggle source

The previous value of the column, which is the initial value of the column before the object was previously saved.

initial_value(:name) # => 'Initial'
update(name: 'Current')
column_previously_was(:name) # => 'Initial'
# File lib/sequel/plugins/dirty.rb, line 147
def column_previously_was(column)
  (pc = @previous_changes) && (val = pc[column]) && val[0]
end
freeze() click to toggle source

Freeze internal data structures

Calls superclass method
# File lib/sequel/plugins/dirty.rb, line 152
def freeze
  initial_values.freeze
  missing_initial_values.freeze
  @previous_changes.freeze if @previous_changes
  super
end
initial_value(column) click to toggle source

The initial value of the given column. If the column value has not changed, this will be the same as the current value of the column.

initial_value(:name) # => 'Initial'
# File lib/sequel/plugins/dirty.rb, line 164
def initial_value(column)
  initial_values.fetch(column){get_column_value(column)}
end
initial_values() click to toggle source

A hash with column symbol keys and initial values.

initial_values # {:name => 'Initial'}
# File lib/sequel/plugins/dirty.rb, line 171
def initial_values
  @initial_values ||= {}
end
reset_column(column) click to toggle source

Reset the column to its initial value. If the column was not set initial, removes it from the values.

reset_column(:name)
name # => 'Initial'
# File lib/sequel/plugins/dirty.rb, line 180
def reset_column(column)
  if initial_values.has_key?(column)
    set_column_value(:"#{column}=", initial_values[column])
  end
  if missing_initial_values.include?(column)
    values.delete(column)
  end
end
will_change_column(column) click to toggle source

Manually specify that a column will change. This should only be used if you plan to modify a column value in place, which is not recommended.

will_change_column(:name)
name.gsub(/i/i, 'o')
column_change(:name) # => ['Initial', 'onotoal']
# File lib/sequel/plugins/dirty.rb, line 195
def will_change_column(column)
  _add_changed_column(column)
  check_missing_initial_value(column)

  value = if initial_values.has_key?(column)
    initial_values[column]
  else
    get_column_value(column)
  end

  initial_values[column] = if value && value != true && value.respond_to?(:clone)
    begin
      value.clone
    rescue TypeError
      value
    end
  else
    value
  end
end

Private Instance Methods

_clear_changed_columns(reason) click to toggle source

Reset initial values when clearing changed columns

Calls superclass method
# File lib/sequel/plugins/dirty.rb, line 219
def _clear_changed_columns(reason)
  reset_initial_values if reason == :initialize || reason == :refresh
  super
end
change_column_value(column, value) click to toggle source

When changing the column value, save the initial column value. If the column value is changed back to the initial value, update changed columns to remove the column.

Calls superclass method
# File lib/sequel/plugins/dirty.rb, line 227
def change_column_value(column, value)
  if (iv = initial_values).has_key?(column)
    initial = iv[column]
    super
    if value == initial
      _changed_columns.delete(column) unless missing_initial_values.include?(column)
      iv.delete(column)
    end
  else
    check_missing_initial_value(column)
    iv[column] = get_column_value(column)
    super
  end
end
check_missing_initial_value(column) click to toggle source

If the values hash does not contain the column, make sure #missing_initial_values does so that it doesn't get deleted from changed_columns if changed back, and so that resetting the column value can be handled correctly.

# File lib/sequel/plugins/dirty.rb, line 245
def check_missing_initial_value(column)
  unless values.has_key?(column) || (miv = missing_initial_values).include?(column)
    miv << column
  end
end
initialize_copy(other) click to toggle source

Duplicate internal data structures

Calls superclass method
# File lib/sequel/plugins/dirty.rb, line 252
def initialize_copy(other)
  super
  @initial_values = Hash[other.initial_values]
  @missing_initial_values = other.send(:missing_initial_values).dup
  @previous_changes = Hash[other.previous_changes] if other.previous_changes
  self
end
missing_initial_values() click to toggle source

Array holding column symbols that were not present initially. This is necessary to differentiate between values that were not present and values that were present but equal to nil.

# File lib/sequel/plugins/dirty.rb, line 263
def missing_initial_values
  @missing_initial_values ||= []
end
reset_initial_values() click to toggle source

Clear the data structures that store the initial values.

# File lib/sequel/plugins/dirty.rb, line 268
def reset_initial_values
  @initial_values.clear if @initial_values
  @missing_initial_values.clear if @missing_initial_values
end