Class: Property::Properties

Inherits:
Hash
  • Object
show all
Includes:
DirtyProperties
Defined in:
lib/property/properties.rb

Constant Summary

Constants included from DirtyProperties

DirtyProperties::CHANGED_REGEXP, DirtyProperties::WAS_REGEXP

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DirtyProperties

#changed, #changed?, #changes, #clear_changes!, #delete, #method_missing

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Property::DirtyProperties

Instance Attribute Details

#ownerObject

Returns the value of attribute owner.



17
18
19
# File 'lib/property/properties.rb', line 17

def owner
  @owner
end

Class Method Details

.json_create(serialized) ⇒ Object



20
21
22
# File 'lib/property/properties.rb', line 20

def self.json_create(serialized)
  self[serialized['data']]
end

Instance Method Details

#[]=(key, value) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/property/properties.rb', line 28

def []=(key, value)
  if column = columns[key]
    if value.blank?
      if default = column.default_for(@owner)
        super(key, default)
      else
        delete(key)
      end
    elsif value.kind_of?(Hash) && column.klass <= Hash && column.caster.respond_to?(:merge_hash)
      orig = self[key]
      # We *MUST* duplicate hash here or Dirty will not function correctly.
      value = column.caster.merge_hash(orig ? orig.dup : {}, value)
      if value.blank?
        if default = column.default_for(@owner)
          super(key, default)
        else
          delete(key)
        end
      else
        super(key, value)
      end
    else
      super(key, column.type_cast(value))
    end
  else
    super
  end
end

#columnsObject



102
103
104
# File 'lib/property/properties.rb', line 102

def columns
  @owner.schema.columns
end

#merge!(attributes) ⇒ Object

We need to write our own merge so that typecasting is called

Raises:

  • (TypeError)


58
59
60
61
62
63
# File 'lib/property/properties.rb', line 58

def merge!(attributes)
  raise TypeError.new("can't convert #{attributes.class} into Hash") unless attributes.kind_of?(Hash)
  attributes.each do |key, value|
    self[key] = value
  end
end

#to_json(*args) ⇒ Object



24
25
26
# File 'lib/property/properties.rb', line 24

def to_json(*args)
  { 'json_class' => self.class.name, 'data' => Hash[self] }.to_json(*args)
end

#validateObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/property/properties.rb', line 65

def validate
  column_names = columns.keys
  errors = @owner.errors
  no_errors = true

  original_hash = @original_hash || self

  bad_keys         = keys - column_names
  missing_keys     = column_names - keys
  keys_to_validate = keys - bad_keys

  bad_keys.each do |key|
    if original_hash[key] == self[key]
      # ignore invalid legacy value
    elsif self[key].blank?
      # ignore blank values
      self.delete(key)
    else
      # We use our own Error class to make sure 'send' is not used on error keys.
      errors.add(key, Property::AttributeError.new(@owner, key, nil, :message => 'property not declared', :value => self[key]))
    end
  end

  missing_keys.each do |key|
    column = columns[key]
    if column.has_default?
      self[key] = column.default_for(@owner)
    end
  end

  keys_to_validate.each do |key|
    columns[key].validate(self[key], errors)
  end

  bad_keys.empty?
end