Module: Decidim::AttributeObject::Model

Overview

This provides a dummy model implementation for replacing the Virtus models using ActiveModel. This class is a lightweight version of ‘ActiveModel::Model` with the `ActiveModel::Attributes` module and its overridden methods.

The main purpose of this class is to provide a backwards compatible API for defining classes that hold attributes, such as the form classes.

Usage:

Replace all instances of `Virtus.model` with `Decidim::AttributeObject::Model`.

Constant Summary

Constants included from TypeMap

TypeMap::Boolean, TypeMap::Decimal

Instance Method Summary collapse

Instance Method Details

#[](attribute_name) ⇒ Object

Convenience method for accessing the attributes through model which is used in multiple places across the code.



121
122
123
# File 'decidim-core/lib/decidim/attribute_object/model.rb', line 121

def [](attribute_name)
  public_send(attribute_name) if respond_to?(attribute_name)
end

#[]=(attribute_name, value) ⇒ Object

Convenience method for settings the attributes through model = “foo” which is used in some places across the code.



127
128
129
# File 'decidim-core/lib/decidim/attribute_object/model.rb', line 127

def []=(attribute_name, value)
  public_send("#{attribute_name}=", value) if respond_to?("#{attribute_name}=")
end

#attributesObject

This provides backwards compatibility for accessing the attributes through symbols by calling ‘obj.attributes` or `obj.attributes.slice(:key1, :key2)`. In the legacy Virtus models, this returned a hash with symbol keys.

Deprecated: Attributes access through symbols is deprecated and may be removed in future versions. Please refactor all your attributes calls to access the attributes through string keys.



115
116
117
# File 'decidim-core/lib/decidim/attribute_object/model.rb', line 115

def attributes
  super.with_indifferent_access
end

#attributes_with_valuesObject

Convenience method used in initiatives



132
133
134
# File 'decidim-core/lib/decidim/attribute_object/model.rb', line 132

def attributes_with_values
  to_h.compact
end

#initialize(attributes = {}) ⇒ Object



63
64
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
101
102
103
104
# File 'decidim-core/lib/decidim/attribute_object/model.rb', line 63

def initialize(attributes = {})
  # Parentheses needed not to pass the arguments.
  super()

  return unless attributes

  # Make sure the attributes is a hash
  base_attributes =
    if attributes.is_a?(Hash)
      attributes
    else
      attributes.to_h
    end

  # Only pass the existing attribute keys to assign_attributes
  # The regular expression matching makes sure we also include the "multi"
  # parameters, such as date fields passed from the view which are
  # formatted as date(1i), date(2i), date(3i). These are converted to
  # hashes below which are handled by the ActiveModel::Attributes types,
  # such as :date.
  correct_attributes = {}.tap do |attrs|
    base_attributes.each do |k, v|
      # Handle "multi" parameter attributes, such as date(1i), date(2i),
      # date(3i). This converts these three attributes to a single hash
      # attribute formatted as:
      #   { "date" => { 1 => ..., 2 => ..., 3 => ...  } }
      mp = k.to_s.match(/(.*)\(([0-9]+i)\)$/)
      if mp
        next unless attribute_names.include?(mp[1])

        attrs[mp[1]] ||= {}
        attrs[mp[1]][mp[2].to_i] = v
      else
        next unless attribute_names.include?(k.to_s)

        attrs[k] = v
      end
    end
  end

  assign_attributes(correct_attributes)
end

#to_hObject Also known as: to_hash



136
137
138
139
140
141
# File 'decidim-core/lib/decidim/attribute_object/model.rb', line 136

def to_h
  hash = attributes.to_h.symbolize_keys
  hash.delete(:id) if hash.has_key?(:id) && hash[:id].blank?

  hash
end