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.


236
237
238
239
240
# File 'lib/mobility/plugins/active_model/dirty.rb', line 236

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


234
235
236
# File 'lib/mobility/plugins/active_model/dirty.rb', line 234

def previous_changes
  @previous_changes
end

Instance Method Details

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


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

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)

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

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


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

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)

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

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


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

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


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

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


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

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

#changedObject


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

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

#changed?Boolean

Returns:

  • (Boolean)

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

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

#changed_attributesObject


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

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


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

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


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

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

#restore_attribute!(attr_name) ⇒ Object


311
312
313
# File 'lib/mobility/plugins/active_model/dirty.rb', line 311

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