Nested Entity

When you specify associations in Repository it automatically defines attribute of an Entity type in corresponding Entity. In case of custom attributes definition you should do it manually




 



class Account < Hanami::Entity
  attributes do
    # ...
    attribute :owner, Types::Entity(UserAuthData)
  end
end
1
2
3
4
5
6

It does not coerce owner attribute JSON data into Entity instance. Well it tries, but Sequel return JSONHash class that has not compatibe keys format.

Nested Entity from PostgreSQL JSON column

We can create custom Entity attr Type definition to construct any type of objects


 



class Account < Hanami::Entity
  attribute :auth_data, Types.JSONBEntity(UserAuthData)
  ...
end
1
2
3
4

here for example we prepare JSON data from DB to be passed into construtor of the entity (in this example UserAuthData is also a simple Entity)

/lib/web/hanami_types.rb




 



module Hanami::Entity::Types
  def self.JSONBEntity(class_const)
    fn = -> attrs { class_const.new(::Hanami::Utils::Hash.deep_symbolize(attrs)) }
    ::Dry::Types::Constructor.new(class_const, &fn)
  end
end
1
2
3
4
5
6

Nested object of any class

When you need to transfer different structured data as an attribuyte of an entity



 



class Post < Hanami::Entity
  attributes do
    attribute :embed, Types::Object
  end
end
1
2
3
4
5
[1] pry(main)> Post.new(embed: Image.new())
=> #<Post @attributes={:embed=>#<Image>}>
[2] pry(main)> Post.new(embed: Url.new())
=> #<Post @attributes={:embed=>#<Url>}>
1
2
3
4

Update Entity

Entity is immutable, so you can not do following

user = User.new(id: 5, name: "iJackUA")
user.name = "Yevhen"
1
2

but you can create a new entity with updated attributes

user = User.new(id: 5, name: "iJackUA")
user_new = User.new(**user, name: "Yevhen")
1
2

also, you can omit creating new var and use update with old entity object:

UserRepository.new.update(user.id, **user, name: 'Yevhen')
1