Module: MetaHash

Defined in:
lib/metahash.rb,
lib/metahash/version.rb

Constant Summary collapse

VERSION =
"1.0.3"

Instance Method Summary collapse

Instance Method Details

#has_metadata(serialized_field = "metadata", serializer: JSON) ⇒ Object

When an active record object is loaded, convert to Metadata. If for whatever reason we lose this Metadata class, we can read the hash by creating class Metadata < Hash; end

Parameters:

  • serialized_field (Symbol) (defaults to: "metadata")

    name of the field to convert to Metadata



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/metahash.rb', line 13

def (serialized_field = "metadata", serializer: JSON)
  # tell Active Record that the field is going to be JSON
  # serialized, because JSON > YAML
  serialize serialized_field, serializer

  after_initialize do |record|
    # first check the type of the field
    # proceed if hash, abort if Metadata
    if record.has_attribute?(serialized_field)
      if [Hash, NilClass].include?(record.send(serialized_field).class)
        # alias the old method / field
        backup_name = "#{serialized_field}_original".to_sym
        # alias_method backup_name, serialized_field
        record.define_singleton_method backup_name, record.method(serialized_field)
        # name the metadata accessor the same as the original field
        # rails should automatically serialize this on save
        initial_value = record.send(backup_name) || {}
        record.send("#{serialized_field}=", Metadata.new(initial_value))
      end
    end
  end


  # create a before_save hook to store a pure Hash in the DB
  before_save do |record|
    @temp_metadata = record.send(serialized_field)
    record.send("#{serialized_field}=", @temp_metadata.to_hash) if @temp_metadata
  end

  # restore the metadata to the field
  after_save do |record|
    record.send("#{serialized_field}=", @temp_metadata) if @temp_metadata
  end

end