Class: Mobility::Plugins::ActiveModel::Dirty::MobilityMutationTracker

Inherits:
Object
  • Object
show all
Defined in:
lib/mobility/plugins/active_model/dirty.rb

Overview

Note:

Seriously, I really don’t want to reproduce all of ActiveModel::Dirty here, but having fought with upstream changes many many times I finally decided it’s more future-proof to just re-implement the stuff we need here, to avoid weird breakage.

Although this is somewhat ugly, at least it’s explicit and since it’s self-defined (rather than hooking into fickle private methods in Rails), it won’t break all of a sudden. We just need to ensure that specs are up-to-date with the latest weird dirty method pattern Rails has decided to support.

Constant Summary collapse

OPTION_NOT_GIVEN =
Object.new

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model) ⇒ MobilityMutationTracker

Returns a new instance of MobilityMutationTracker.



242
243
244
245
246
# File 'lib/mobility/plugins/active_model/dirty.rb', line 242

def initialize(model)
  @model = model
  @current_changes = {}.with_indifferent_access
  @previous_changes = {}.with_indifferent_access
end

Instance Attribute Details

#previous_changesObject (readonly)

Returns the value of attribute previous_changes.



240
241
242
# File 'lib/mobility/plugins/active_model/dirty.rb', line 240

def previous_changes
  @previous_changes
end

Instance Method Details

#attribute_change(attr_name) ⇒ Object Also known as: attribute_change_to_be_saved



277
278
279
280
281
# File 'lib/mobility/plugins/active_model/dirty.rb', line 277

def attribute_change(attr_name)
  if attribute_changed?(attr_name)
    [attribute_was(attr_name), fetch_value(attr_name)]
  end
end

#attribute_changed?(attr_name, from: OPTION_NOT_GIVEN, to: OPTION_NOT_GIVEN) ⇒ Boolean Also known as: will_save_change_to_attribute?

Returns:

  • (Boolean)


295
296
297
298
299
# File 'lib/mobility/plugins/active_model/dirty.rb', line 295

def attribute_changed?(attr_name, from: OPTION_NOT_GIVEN, to: OPTION_NOT_GIVEN)
  current_changes.include?(attr_name) &&
    (OPTION_NOT_GIVEN == from || attribute_was(attr_name) == from) &&
    (OPTION_NOT_GIVEN == to || fetch_value(attr_name) == to)
end

#attribute_previous_change(attr_name) ⇒ Object Also known as: saved_change_to_attribute



283
284
285
# File 'lib/mobility/plugins/active_model/dirty.rb', line 283

def attribute_previous_change(attr_name)
  previous_changes[attr_name]
end

#attribute_previously_changed?(attr_name) ⇒ Boolean Also known as: saved_change_to_attribute?

Returns:

  • (Boolean)


301
302
303
# File 'lib/mobility/plugins/active_model/dirty.rb', line 301

def attribute_previously_changed?(attr_name)
  previous_changes.include?(attr_name)
end

#attribute_previously_was(attr_name) ⇒ Object Also known as: attribute_before_last_save



287
288
289
290
291
292
293
# File 'lib/mobility/plugins/active_model/dirty.rb', line 287

def attribute_previously_was(attr_name)
  if attribute_previously_changed?(attr_name)
    # Calling +first+ here fetches the value before change from the
    # hash.
    previous_changes[attr_name].first
  end
end

#attribute_was(attr_name) ⇒ Object Also known as: attribute_in_database



305
306
307
308
309
310
311
# File 'lib/mobility/plugins/active_model/dirty.rb', line 305

def attribute_was(attr_name)
  if attribute_changed?(attr_name)
    current_changes[attr_name]
  else
    fetch_value(attr_name)
  end
end

#attribute_will_change!(attr_name) ⇒ Object



313
314
315
# File 'lib/mobility/plugins/active_model/dirty.rb', line 313

def attribute_will_change!(attr_name)
  current_changes[attr_name] = fetch_value(attr_name) unless current_changes.include?(attr_name)
end

#changedObject



253
254
255
# File 'lib/mobility/plugins/active_model/dirty.rb', line 253

def changed
  attr_names.select { |attr_name| attribute_changed?(attr_name) }
end

#changed?Boolean

Returns:

  • (Boolean)


273
274
275
# File 'lib/mobility/plugins/active_model/dirty.rb', line 273

def changed?
  attr_names.any? { |attr| attribute_changed?(attr) }
end

#changed_attributesObject



257
258
259
260
261
262
263
# File 'lib/mobility/plugins/active_model/dirty.rb', line 257

def changed_attributes
  attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
    if attribute_changed?(attr_name)
      result[attr_name] = attribute_was(attr_name)
    end
  end
end

#changesObject



265
266
267
268
269
270
271
# File 'lib/mobility/plugins/active_model/dirty.rb', line 265

def changes
  attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
    if change = attribute_change(attr_name)
      result.merge!(attr_name => change)
    end
  end
end

#finalize_changesObject



248
249
250
251
# File 'lib/mobility/plugins/active_model/dirty.rb', line 248

def finalize_changes
  @previous_changes = changes
  @current_changes = {}.with_indifferent_access
end

#restore_attribute!(attr_name) ⇒ Object



317
318
319
# File 'lib/mobility/plugins/active_model/dirty.rb', line 317

def restore_attribute!(attr_name)
  current_changes.delete(attr_name)
end