Class: Hanami::Entity

Inherits:
Object
  • Object
show all
Defined in:
lib/hanami/entity.rb,
lib/hanami/entity/schema.rb

Overview

An object that is defined by its identity. See “Domain Driven Design” by Eric Evans.

An entity is the core of an application, where the part of the domain logic is implemented. It's a small, cohesive object that expresses coherent and meaningful behaviors.

It deals with one and only one responsibility that is pertinent to the domain of the application, without caring about details such as persistence or validations.

This simplicity of design allows developers to focus on behaviors, or message passing if you will, which is the quintessence of Object Oriented Programming.

If we expand the code above in **pure Ruby**, it would be:

*Hanami::Model* ships `Hanami::Entity` for developers's convenience.

*Hanami::Model* depends on a narrow and well-defined interface for an Entity - `#id`, `#id=`, `#initialize(attributes={})`.If your object implements that interface then that object can be used as an Entity in the *Hanami::Model* framework.

However, we suggest to implement this interface by including `Hanami::Entity`, in case that future versions of the framework will expand it.

See Dependency Inversion Principle for more on interfaces.

Examples:

With Hanami::Entity

require 'hanami/model'

class Person
  include Hanami::Entity
end

Pure Ruby

class Person
  attr_accessor :id, :name, :age

  def initialize(attributes = {})
    @id, @name, @age = attributes.values_at(:id, :name, :age)
  end
end

See Also:

Since:

  • 0.1.0

Defined Under Namespace

Modules: ClassMethods, Types Classes: Schema

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = nil) ⇒ Hanami::Entity

Instantiate a new entity

Raises:

  • (TypeError)

    if the given attributes are invalid

Since:

  • 0.1.0


123
124
125
126
# File 'lib/hanami/entity.rb', line 123

def initialize(attributes = nil)
  @attributes = self.class.schema[attributes]
  freeze
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m) ⇒ Object

Handle dynamic accessors

If internal attributes set has the requested key, it returns the linked value, otherwise it raises a NoMethodError

Since:

  • 0.7.0


143
144
145
146
# File 'lib/hanami/entity.rb', line 143

def method_missing(m, *)
  attribute?(m) or super # rubocop:disable Style/AndOr
  attributes.fetch(m, nil)
end

Instance Attribute Details

#attributesObject (readonly, private)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0


206
207
208
# File 'lib/hanami/entity.rb', line 206

def attributes
  @attributes
end

Class Method Details

.inherited(klass) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 0.7.0


107
108
109
110
111
112
# File 'lib/hanami/entity.rb', line 107

def self.inherited(klass)
  klass.class_eval do
    @schema = Schema.new
    extend  ClassMethods
  end
end

Instance Method Details

#==(other) ⇒ FalseClass, TrueClass

Implement generic equality for entities

Two entities are equal if they are instances of the same class and they have the same id.

Since:

  • 0.1.0


158
159
160
161
# File 'lib/hanami/entity.rb', line 158

def ==(other)
  self.class == other.class &&
    id == other.id
end

#attribute?(name) ⇒ Boolean (protected)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if the attribute is allowed to be read

Since:

  • 0.7.0


198
199
200
# File 'lib/hanami/entity.rb', line 198

def attribute?(name)
  self.class.schema.attribute?(name)
end

#freezeObject

Freeze the entity

Since:

  • 0.7.0


175
176
177
178
# File 'lib/hanami/entity.rb', line 175

def freeze
  attributes.freeze
  super
end

#hashInteger

Implement predictable hashing for hash equality

Since:

  • 0.7.0


168
169
170
# File 'lib/hanami/entity.rb', line 168

def hash
  [self.class, id].hash
end

#idObject, NilClass

Entity ID

Since:

  • 0.7.0


133
134
135
# File 'lib/hanami/entity.rb', line 133

def id
  attributes.fetch(:id, nil)
end

#respond_to_missing?(name, _include_all) ⇒ Boolean (private)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 0.7.0


210
211
212
# File 'lib/hanami/entity.rb', line 210

def respond_to_missing?(name, _include_all)
  attribute?(name)
end

#to_hHash Also known as: to_hash

Serialize entity to a Hash

Since:

  • 0.1.0


185
186
187
# File 'lib/hanami/entity.rb', line 185

def to_h
  attributes.deep_dup.to_h
end