Module: Shamu::Attributes

Extended by:
ActiveSupport::Concern
Included in:
Entities::Entity, Entities::ListScope, Entities::ListScope::ScopedPaging::PageScope, Events::Message, Features::Context, JsonApi::Rails::Pagination, Services::ObservedRequest, Services::Request
Defined in:
lib/shamu/attributes.rb,
lib/shamu/attributes/equality.rb,
lib/shamu/attributes/assignment.rb,
lib/shamu/attributes/camel_case.rb,
lib/shamu/attributes/validation.rb,
lib/shamu/attributes/validators.rb,
lib/shamu/attributes/html_sanitation.rb,
lib/shamu/attributes/fluid_assignment.rb,
lib/shamu/attributes/validators/valid_validator.rb

Overview

Provide attributes that project data from another source (such as an external API, ActiveRecord model, cached data, etc.) providing simple transformations.

To add additional attribute functionality see

Examples:


class Person
  include Shamu::Attributes

  attribute :name
end

Defined Under Namespace

Modules: Assignment, CamelCase, Equality, FluidAssignment, HtmlSanitation, Validation, Validators

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.association(name, *args, **options, &block) ⇒ self

Define an attribute that defines an association to another resource that also has it's own attributes.

Parameters:

  • name (Symbol)

    of the attribute.

  • as (Symbol)

    an alias of the attribute.

  • on (Symbol)

    another method on the class to delegate the attribute to.

  • default (Object, #call)

    value if not set.

  • build (Class, #call)

    method used to build a nested object on assignment of a hash with nested keys.

  • serialize (Boolean)

    true if the attribute should be included in #to_attributes. Default true.

Yield Returns:

  • the value of the attribute. The result is memoized so the block is only invoked once.

Returns:

  • (self)


230
231
232
233
234
# File 'lib/shamu/attributes.rb', line 230

def association( name, *args, **options, &block )
  options[:association] = true

  attribute( name, *args, **options, &block )
end

.associationsHash

Returns of all association attributes defined on the class.

Returns:

  • (Hash)

    of all association attributes defined on the class.



178
179
180
# File 'lib/shamu/attributes.rb', line 178

def associations
  attributes.select { |_, v| v[:association] }
end

.attribute(name, on: , default: , build: , &block) ⇒ self .attribute(name, build, on: , default: , &block) ⇒ self

Define a new attribute for the class.

Parameters:

  • name (Symbol)

    of the attribute.

  • as (Symbol)

    an alias of the attribute.

  • on (Symbol)

    another method on the class to delegate the attribute to.

  • default (Object, #call)

    value if not set.

  • build (Class, #call)

    method used to build a nested object on assignment of a hash with nested keys.

  • serialize (Boolean)

    true if the attribute should be included in #to_attributes. Default true.

Yield Returns:

  • the value of the attribute. The result is memoized so the block is only invoked once.

Returns:

  • (self)


205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/shamu/attributes.rb', line 205

def attribute( name, *args, **options, &block )
  name    = name.to_sym
  options = create_attribute( name, *args, **options )

  define_attribute_reader( name, **options )
  define_attribute_assignment( name, **options )

  if options.key?( :on )
    define_delegate_fetcher( name, options[:on], options[:build] )
  else
    define_virtual_fetcher( name, options[:default], &block )
  end

  private :"fetch_#{ name }"
  private :"assign_#{ name }"

  self
end

.attributesHash

Returns of attributes and their options defined on the class.

Returns:

  • (Hash)

    of attributes and their options defined on the class.



173
174
175
# File 'lib/shamu/attributes.rb', line 173

def attributes
  @attributes ||= {}
end

Instance Method Details

#[](name) ⇒ Object

Access an attribute using a Hash like index.

Parameters:

  • name (Symbol)

    of the attribute.

Returns:

  • (Object)


69
70
71
# File 'lib/shamu/attributes.rb', line 69

def []( name )
  send name if attribute?( name )
end

#as_json(options = {}) ⇒ Hash

Returns the assigned attributes as a hash for JSON serialization.

Returns:

  • (Hash)

    the assigned attributes as a hash for JSON serialization.



80
81
82
# File 'lib/shamu/attributes.rb', line 80

def as_json( options = {} ) # rubocop:disable Styles/OptionHash
  to_attributes( options.slice( :only, :except ) ).as_json
end

#assign_attributes(attributes) ⇒ self

Assign a hash of values to the matching instance variables.

Parameters:

  • attributes (Hash)

    to assign.

Returns:

  • (self)


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/shamu/attributes.rb', line 126

def assign_attributes( attributes )
  attributes = resolve_attributes( attributes )

  self.class.attributes.each do |key, options|
    as = options[ :as ] # Alias support
    next unless attributes.key?( key ) || ( as && attributes.key?( as ) )
    value = attributes[ key ]
    value ||= attributes[ as ] if as

    if build = options[:build]
      value = build_value( build, value )
    end

    send :"assign_#{ key }", value
  end
end

#attribute?(name) ⇒ Boolean Also known as: key?

Indicates if the object has an attribute with the given name. Aliased to #key? to make the object look like a Hash.

Returns:

  • (Boolean)


61
62
63
# File 'lib/shamu/attributes.rb', line 61

def attribute?( name )
  self.class.attributes.key?( name.to_sym )
end

#initialize(*attributes) ⇒ Object



35
36
37
# File 'lib/shamu/attributes.rb', line 35

def initialize( *attributes )
  assign_attributes( attributes.last )
end

#pretty_print(pp) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/shamu/attributes.rb', line 89

def pretty_print( pp )
  attributes = to_attributes

  pp.object_address_group( self ) do
    pp.seplist( attributes.keys, -> { pp.text "," } ) do |name|
      pp.breakable " "
      pp.group( 1 ) do
        pp.text name.to_s
        pp.text ":"
        pp.breakable " "
        pp.pp attributes[ name ]
      end
    end
  end
end

#set?(attribute) ⇒ Boolean

Returns true if the attribute has been set.

Parameters:

  • attribute (Symbol)

    name.

Returns:

  • (Boolean)

    true if the attribute has been set.



75
76
77
# File 'lib/shamu/attributes.rb', line 75

def set?( attribute )
  instance_variable_defined? :"@#{ attribute }"
end

#slice(*names) ⇒ Hash

Returns a hash with the keys for each of the given names.

Returns:

  • (Hash)

    a hash with the keys for each of the given names.



55
56
57
# File 'lib/shamu/attributes.rb', line 55

def slice( *names )
  to_attributes only: names
end

#to_attributes(only: nil, except: nil) ⇒ Hash

Project the current state of the object to a hash of attributes that can be used to restore the attribute object at a later time.

Parameters:

  • only (Array, Regex) (defaults to: nil)

    include matching attributes

  • except (Array, Regex) (defaults to: nil)

    matching attributes

Returns:

  • (Hash)

    of attributes



45
46
47
48
49
50
51
52
# File 'lib/shamu/attributes.rb', line 45

def to_attributes( only: nil, except: nil )
  self.class.attributes.each_with_object({}) do |(name, options), attrs|
    next if ( only && !match_attribute?( only, name ) ) || ( except && match_attribute?( except, name ) )
    next unless serialize_attribute?( name, options )

    attrs[name] = send( name )
  end
end

#to_json(options = {}) ⇒ String

Returns JSON encoded version of the assigned attributes.

Returns:

  • (String)

    JSON encoded version of the assigned attributes.



85
86
87
# File 'lib/shamu/attributes.rb', line 85

def to_json( options = {} ) # rubocop:disable Styles/OptionHash
  as_json( options ).to_json
end