【问题标题】:How to update only changed attributes in Hanami Model?如何仅更新 Hanami 模型中更改的属性?
【发布时间】:2018-08-15 00:24:58
【问题描述】:

鉴于我使用的是 Hanami Model 版本 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 获取所有更改的属性,但我不知道如何使用这些属性部分更新实体。

有没有办法做到这一点?

【问题讨论】:

  • 您无法升级到 v0.7.0 的任何具体原因?这样您就可以使用 update 来更新 id 和要更新的数据。
  • 该软件是一个庞大的单体,升级它并不容易,因为这种升级需要处理一些新概念,例如不可变实体。我们正在努力解决这个问题,但我想知道这个问题是否有替代方案。解决办法是升级。

标签: ruby hanami hanami-model


【解决方案1】:

hanami 实体是一种不可变的数据结构。这就是为什么您不能使用 setter 更改数据的原因:

>> 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"

【讨论】:

    猜你喜欢
    • 2010-10-27
    • 1970-01-01
    • 2016-05-23
    • 2021-11-27
    • 2018-05-18
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    相关资源
    最近更新 更多