Как обновить только измененные атрибуты в модели Hanami?

Учитывая, что я использую модель Hanami версии 0.6.1, я бы хотел, чтобы хранилище обновляло только измененные атрибуты сущности.

Например:

user_instance1 = UserRepository.find(1)
user_instance1.name = 'John'

user_instance2 = UserRepository.find(1)
user_instance2.email = 'john@email.com'

UserRepository.update(user_instance1)
#expected: UPDATE USER SET NAME = 'John' WHERE ID = 1

UserRepository.update(user_instance2)
#expected: UPDATE USER SET EMAIL = 'john@email.com' WHERE ID = 1

Но получается, что вторая команда переопределяет все поля, включая те, которые не были изменены.

Я знаю, что могу использовать Hanami::Entity::DirtyTracking чтобы получить все измененные атрибуты, но я не знаю, как частично обновить сущность с этими атрибутами.

Есть ли способ сделать это?

1 ответ

Решение

Сущность Ханами является неизменной структурой данных. Вот почему вы не можете изменить данные с помощью сеттеров:

>> account = AccountRepository.new.first
=> #<Account:0x00007ffbf3918010 @attributes={ name: 'Anton', ...}>

>> account.name
=> "Anton"

>> account.name = "Other"
        1: from /Users/anton/.rvm/gems/ruby-2.5.0/gems/hanami-model-1.2.0/lib/hanami/entity.rb:144:in `method_missing'
NoMethodError (undefined method `name=' for #<Account:0x00007ffbf3918010>)

Вместо этого вы можете создать новый объект, например:

# will return a new account entity with updated attributes
>> Account.new(**account, name: 'A new one')

А также, вы можете использовать #update со старым объектом:

>> AccountRepository.new.update(account.id, **account, name: 'A new name')
=> #<Account:0x00007ffbf3918010 @attributes={ name: 'Anton', ...}>

>> account = AccountRepository.new.first
=> #<Account:0x00007ffbf3918010 @attributes={ name: 'Anton', ...}>

>> account.name
=> "A new name"
Другие вопросы по тегам