Class: AttrMasker::Attribute

Inherits:
Object
  • Object
show all
Defined in:
lib/attr_masker/attribute.rb

Overview

Holds the definition of maskable attribute.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, model, options) ⇒ Attribute

Returns a new instance of Attribute.



9
10
11
12
13
# File 'lib/attr_masker/attribute.rb', line 9

def initialize(name, model, options)
  @name = name.to_sym
  @model = model
  @options = options
end

Instance Attribute Details

#modelObject (readonly)

Returns the value of attribute model.



7
8
9
# File 'lib/attr_masker/attribute.rb', line 7

def model
  @model
end

#nameObject (readonly)

Returns the value of attribute name.



7
8
9
# File 'lib/attr_masker/attribute.rb', line 7

def name
  @name
end

#optionsObject (readonly)

Returns the value of attribute options.



7
8
9
# File 'lib/attr_masker/attribute.rb', line 7

def options
  @options
end

Instance Method Details

#column_namesObject



76
77
78
# File 'lib/attr_masker/attribute.rb', line 76

def column_names
  options[:column_names] || [name]
end

#evaluate_option(option_name, model_instance) ⇒ Object

Evaluates option (typically :if or :unless) on given model instance. That option can be either a proc (a model is passed as an only argument), or a symbol (a method of that name is called on model instance).



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/attr_masker/attribute.rb', line 52

def evaluate_option(option_name, model_instance)
  option = options[option_name]

  if option.is_a?(Symbol)
    model_instance.send(option)
  elsif option.respond_to?(:call)
    option.call(model_instance)
  else
    option
  end
end

#marshal_data(data) ⇒ Object



64
65
66
67
68
# File 'lib/attr_masker/attribute.rb', line 64

def marshal_data(data)
  return data unless options[:marshal]

  options[:marshaler].send(options[:dump_method], data)
end

#mask(model_instance) ⇒ Object

Mask the attribute on given model. Masking will be performed regardless of :if and :unless options. A should_mask? method should be called separately to ensure that given object is eligible for masking.

The method returns the masked value but does not modify the object’s attribute.

If marshal attribute’s option is true, the attribute value will be loaded before masking, and dumped to proper storage format prior returning.



35
36
37
38
39
40
41
# File 'lib/attr_masker/attribute.rb', line 35

def mask(model_instance)
  value = unmarshal_data(model_instance.send(name))
  masker = options[:masker]
  masker_value = masker.call(value: value, model: model_instance,
                             attribute_name: name, masking_options: options)
  model_instance.send("#{name}=", marshal_data(masker_value))
end

#masked_attributes_new_values(model_instance) ⇒ Object

Returns a hash of maskable attribute names, and respective attribute values. Unchanged attributes are skipped.



45
46
47
# File 'lib/attr_masker/attribute.rb', line 45

def masked_attributes_new_values(model_instance)
  model_instance.changes.slice(*column_names).transform_values(&:second)
end

#should_mask?(model_instance) ⇒ Boolean

Evaluates the :if and :unless attribute options on given instance. Returns true or false, depending on whether the attribute should be masked for this object or not.

Returns:

  • (Boolean)


18
19
20
21
22
23
# File 'lib/attr_masker/attribute.rb', line 18

def should_mask?(model_instance)
  not (
    options.key?(:if) && !evaluate_option(:if, model_instance) ||
    options.key?(:unless) && evaluate_option(:unless, model_instance)
  )
end

#unmarshal_data(data) ⇒ Object



70
71
72
73
74
# File 'lib/attr_masker/attribute.rb', line 70

def unmarshal_data(data)
  return data unless options[:marshal]

  options[:marshaler].send(options[:load_method], data)
end