Class: SimpleAcp::Models::Base Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/simple_acp/models/base.rb

Overview

This class is abstract.

Subclass and use Base.attribute to define attributes

Base class for all ACP models providing common serialization.

Provides a simple DSL for declaring attributes with defaults, automatic JSON serialization/deserialization, and equality comparisons.

Examples:

Defining a model

class MyModel < Base
  attribute :name, required: true
  attribute :count, default: 0
  attribute :tags, default: -> { [] }
end

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**kwargs) ⇒ Base

Initialize with keyword arguments.

Parameters:

  • kwargs (Hash) —

    attribute values



81
82
83
84
85
86
# File 'lib/simple_acp/models/base.rb', line 81

def initialize(**kwargs)
  self.class.attributes.each do |name, opts|
    value = kwargs.fetch(name) { opts[:default].is_a?(Proc) ? opts[:default].call : opts[:default] }
    instance_variable_set(:"@#{name}", value)
  end
end

Class Method Details

.attribute(name, type: nil, default: nil, required: false) ⇒ void

This method returns an undefined value.

Define an attribute on this model.

Parameters:

  • name (Symbol) —

    the attribute name

  • type (Class, nil) (defaults to: nil) —

    optional type hint (for documentation)

  • default (Object, Proc, nil) (defaults to: nil) —

    default value or proc

  • required (Boolean) (defaults to: false) —

    whether the attribute is required



27
28
29
30
31
32
33
34
35
36
# File 'lib/simple_acp/models/base.rb', line 27

def attribute(name, type: nil, default: nil, required: false)
  @attributes ||= {}
  @attributes[name] = { type: type, default: default, required: required }

  attr_reader name

  define_method(:"#{name}=") do |value|
    instance_variable_set(:"@#{name}", value)
  end
end

.attributes ⇒ Hash<Symbol, Hash>

Get all attributes including inherited ones.

Returns:

  • (Hash<Symbol, Hash>) —

    attribute definitions



41
42
43
44
45
46
47
48
49
50
# File 'lib/simple_acp/models/base.rb', line 41

def attributes
  @attributes ||= {}

  # Inherit attributes from parent class
  if superclass.respond_to?(:attributes)
    superclass.attributes.merge(@attributes)
  else
    @attributes
  end
end

.from_hash(hash) ⇒ Base? Also known as: from_h

Create an instance from a hash.

Parameters:

  • hash (Hash, nil) —

    attribute values (string or symbol keys)

Returns:

  • (Base, nil) —

    the new instance or nil if hash is nil



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/simple_acp/models/base.rb', line 63

def from_hash(hash)
  return nil if hash.nil?

  instance = new
  attributes.each do |name, _opts|
    key = name.to_s
    value = hash.key?(key) ? hash[key] : hash[name]
    instance.send(:"#{name}=", value) unless value.nil?
  end
  instance
end

.own_attributes ⇒ Hash<Symbol, Hash>

Get only attributes defined on this class (not inherited).

Returns:

  • (Hash<Symbol, Hash>) —

    attribute definitions



55
56
57
# File 'lib/simple_acp/models/base.rb', line 55

def own_attributes
  @attributes ||= {}
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Check equality based on all attributes.

Parameters:

  • other (Object) —

    object to compare

Returns:

  • (Boolean) —

    true if same class and all attributes equal



112
113
114
115
116
117
118
# File 'lib/simple_acp/models/base.rb', line 112

def ==(other)
  return false unless other.is_a?(self.class)

  self.class.attributes.keys.all? do |name|
    send(name) == other.send(name)
  end
end

#hash ⇒ Integer

Compute hash based on all attributes.

Returns:

  • (Integer) —

    hash code



125
126
127
# File 'lib/simple_acp/models/base.rb', line 125

def hash
  self.class.attributes.keys.map { |name| send(name) }.hash
end

#to_h ⇒ Hash

Convert to a hash for JSON serialization.

Returns:

  • (Hash) —

    attribute values (nil values excluded)



91
92
93
94
95
96
97
98
# File 'lib/simple_acp/models/base.rb', line 91

def to_h
  self.class.attributes.each_with_object({}) do |(name, _opts), hash|
    value = send(name)
    next if value.nil?

    hash[name] = serialize_value(value)
  end
end

#to_json(*args) ⇒ String

Convert to JSON string.

Parameters:

  • args (Array) —

    arguments passed to Hash#to_json

Returns:

  • (String) —

    JSON representation



104
105
106
# File 'lib/simple_acp/models/base.rb', line 104

def to_json(*args)
  to_h.to_json(*args)
end