Module: Lotus::Entity

Defined in:
lib/lotus/entity.rb,
lib/lotus/entity/dirty_tracking.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.

When a class includes ‘Lotus::Entity` it receives the following interface:

* #id
* #id=
* #initialize(attributes = {})

‘Lotus::Entity` also provides the `.attributes=` for defining attribute accessors for the given names.

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

Lotus::Model ships ‘Lotus::Entity` for developers’s convenience.

Lotus::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 Lotus::Model framework.

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

See Dependency Inversion Principle for more on interfaces.

Examples:

With Lotus::Entity

require 'lotus/model'

class Person
  include Lotus::Entity
  attributes :name, :age
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, DirtyTracking

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

Inject the public API into the hosting class.

Examples:

With Object

require 'lotus/model'

class User
  include Lotus::Entity
end

With Struct

require 'lotus/model'

User = Struct.new(:id, :name) do
  include Lotus::Entity
end

Since:

  • 0.1.0



81
82
83
84
85
86
# File 'lib/lotus/entity.rb', line 81

def self.included(base)
  base.class_eval do
    extend ClassMethods
    attributes :id
  end
end

Instance Method Details

#==(other) ⇒ Object

Overrides the equality Ruby operator

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

Since:

  • 0.1.0



207
208
209
210
# File 'lib/lotus/entity.rb', line 207

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

#initialize(attributes = {}) ⇒ Object

Defines a generic, inefficient initializer, in case that the attributes weren’t explicitly defined with ‘.attributes=`.

Parameters:

  • attributes (Hash) (defaults to: {})

    a set of attribute names and values

Raises:

  • NoMethodError in case the given attributes are trying to set unknown or private methods.

See Also:

  • attributes

Since:

  • 0.1.0



194
195
196
197
198
199
# File 'lib/lotus/entity.rb', line 194

def initialize(attributes = {})
  attributes.each do |k, v|
    setter = "#{ k }="
    public_send(setter, v) if respond_to?(setter)
  end
end

#to_hObject

Return the hash of attributes

Examples:

require 'lotus/model'
class User
  include Lotus::Entity
  attributes :name
end

user = User.new(id: 23, name: 'Luca')
user.to_h # => { :id => 23, :name => "Luca" }

Since:

  • 0.2.0



225
226
227
# File 'lib/lotus/entity.rb', line 225

def to_h
  Hash[self.class.attributes.map { |a| [a, public_send(a)] }]
end

#update(attributes = {}) ⇒ Object

Set attributes for entity

Examples:

require 'lotus/model'
class User
  include Lotus::Entity
  attributes :name
end

user = User.new(name: 'Lucca')
user.update(name: 'Luca')
user.name # => 'Luca'

Since:

  • 0.2.0



243
244
245
246
247
# File 'lib/lotus/entity.rb', line 243

def update(attributes={})
  attributes.each do |attribute, value|
    public_send("#{attribute}=", value)
  end
end