Module: AttrJson::Record

Extended by:
ActiveSupport::Concern
Defined in:
lib/attr_json/record.rb,
lib/attr_json/record/query_scopes.rb,
lib/attr_json/record/query_builder.rb

Overview

The mix-in to provide AttrJson support to ActiveRecord::Base models. We call it Record instead of ActiveRecord to avoid confusing namespace shadowing errors, sorry!

Examples:

class SomeModel < ActiveRecord::Base
  include AttrJson::Record

  attr_json :a_number, :integer
end

Defined Under Namespace

Modules: QueryScopes Classes: QueryBuilder

Instance Method Summary collapse

Instance Method Details

#attr_json_sync_to_rails_attributesObject

Sync all values FROM the json_attributes json column TO rails attributes

If values have for some reason gotten out of sync this will make them the identical objects again, with the container hash value being the source.

In some cases, the values may already be equivalent but different objects -- This is meant to ensure they are the same object in both places, so mutation of mutable object will effect both places, for instance for dirty tracking.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/attr_json/record.rb', line 52

def attr_json_sync_to_rails_attributes
  self.class.attr_json_registry.definitions.group_by(&:container_attribute).each_pair do |container_attribute, definitions|
    begin
      # column may have eg been left out of an explicit 'select'
      next unless has_attribute?(container_attribute)

      container_value    = public_send(container_attribute)

      # isn't expected to be possible to be nil rather than empty hash, but
      # if it is from some edge case, well, we don't have values to sync, fine
      next if container_value.nil?

      definitions.each do |attribute_def|
        attr_name     = attribute_def.name
        value         = container_value[attribute_def.store_key]

        if value
          # TODO, can we just make this use the setter?
          write_attribute(attr_name, value)

          clear_attribute_change(attr_name) if persisted?

          # writing and clearning will result in a new object stored in
          # rails attributes, we want
          # to make sure the exact same object is in the json attribute,
          # so in-place mutation changes to it are reflected in both places.
          container_value[attribute_def.store_key] = read_attribute(attr_name)
        end
      end
    rescue AttrJson::Type::Model::BadCast, AttrJson::Type::PolymorphicModel::TypeError => e
      # There was bad data in the DB, we're just going to skip the Rails attribute sync.
      # Should we log?
    end
  end
end