Module: NoBrainer::Document::Attributes

Extended by:
ActiveSupport::Concern
Includes:
ActiveModel::ForbiddenAttributesProtection
Defined in:
lib/no_brainer/document/attributes.rb

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

VALID_FIELD_OPTIONS =
[:index, :default, :type, :readonly, :primary_key,
:lazy_fetch, :store_as, :validates, :required, :unique,
:uniq, :format, :in, :length, :min_length, :max_length,
:prefix, :suffix, :virtual]
RESERVED_FIELD_NAMES =
[:index, :default, :and, :or, :selector, :associations, :pk_value] +
NoBrainer::SymbolDecoration::OPERATORS

Instance Method Summary collapse

Instance Method Details

#[](*args) ⇒ Object



45
# File 'lib/no_brainer/document/attributes.rb', line 45

def [](*args); read_attribute(*args); end

#[]=(*args) ⇒ Object



50
# File 'lib/no_brainer/document/attributes.rb', line 50

def []=(*args); write_attribute(*args); end

#_initialize(attrs = {}, options = {}) ⇒ Object



17
18
19
20
# File 'lib/no_brainer/document/attributes.rb', line 17

def _initialize(attrs={}, options={})
  @_attributes = {}.with_indifferent_access
  assign_attributes(attrs, options.reverse_merge(:pristine => true))
end

#_read_attribute(name) ⇒ Object



34
35
36
# File 'lib/no_brainer/document/attributes.rb', line 34

def _read_attribute(name)
  @_attributes[name]
end

#_write_attribute(name, value) ⇒ Object



38
39
40
# File 'lib/no_brainer/document/attributes.rb', line 38

def _write_attribute(name, value)
  @_attributes[name] = value
end

#assign_attributes(attrs, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/no_brainer/document/attributes.rb', line 72

def assign_attributes(attrs, options={})
  attrs = attrs.to_h if !attrs.is_a?(Hash) && attrs.respond_to?(:to_h)
  raise ArgumentError, "To assign attributes, please pass a hash instead of `#{attrs.class}'" unless attrs.is_a?(Hash)

  if options[:pristine]
    if options[:keep_ivars] && options[:missing_attributes].try(:[], :pluck)
      options[:missing_attributes][:pluck].keys.each { |k| @_attributes.delete(k) }
    else
      @_attributes.clear
    end
  end

  if options[:from_db]
    attrs = self.class.with_fields_reverse_aliased(attrs)
    @_attributes.merge!(attrs)
    clear_dirtiness(options)
  else
    clear_dirtiness(options) if options[:pristine]
    attrs = sanitize_for_mass_assignment(attrs)
    attrs.each { |k,v| self.write_attribute(k,v) }
  end
  assign_defaults(options) if options[:pristine]
  self
end

#assign_defaults(options) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/no_brainer/document/attributes.rb', line 52

def assign_defaults(options)
  self.class.fields.each do |name, field_options|
    # :default => nil will not set the value to nil, but :default => ->{ nil } will.
    # This is useful to unset a default value.

    next if field_options[:default].nil? || @_attributes.key?(name)

    if opt = options[:missing_attributes]
      if (opt[:pluck] && !opt[:pluck][name]) ||
         (opt[:without] && opt[:without][name])
        next
      end
    end

    default_value = field_options[:default]
    default_value = instance_exec(&default_value) if default_value.is_a?(Proc)
    self.write_attribute(name, default_value)
  end
end

#attributesObject



26
27
28
# File 'lib/no_brainer/document/attributes.rb', line 26

def attributes
  Hash[readable_attributes.map { |k| [k, read_attribute(k)] }].with_indifferent_access.freeze
end

#inspectObject



106
107
108
# File 'lib/no_brainer/document/attributes.rb', line 106

def inspect
  "#<#{self.class} #{inspectable_attributes.map { |k,v| "#{k}: #{v.inspect}" }.join(', ')}>"
end

#inspectable_attributesObject



97
98
99
100
# File 'lib/no_brainer/document/attributes.rb', line 97

def inspectable_attributes
  # TODO test that thing
  Hash[@_attributes.sort_by { |k,v| self.class.fields.keys.index(k.to_sym) || 2**10 }].with_indifferent_access.freeze
end

#raw_attributesObject



30
31
32
# File 'lib/no_brainer/document/attributes.rb', line 30

def raw_attributes
  @_attributes
end

#read_attribute(name) ⇒ Object



42
43
44
# File 'lib/no_brainer/document/attributes.rb', line 42

def read_attribute(name)
  __send__("#{name}")
end

#readable_attributesObject



22
23
24
# File 'lib/no_brainer/document/attributes.rb', line 22

def readable_attributes
  @_attributes.keys & self.class.fields.keys.map(&:to_s)
end

#to_sObject



102
103
104
# File 'lib/no_brainer/document/attributes.rb', line 102

def to_s
  "#<#{self.class} #{self.class.pk_name}: #{self.pk_value.inspect}>"
end

#write_attribute(name, value) ⇒ Object



47
48
49
# File 'lib/no_brainer/document/attributes.rb', line 47

def write_attribute(name, value)
  __send__("#{name}=", value)
end