【问题标题】:Rails merge temporary attributes to model objectRails 将临时属性合并到模型对象
【发布时间】:2021-03-14 15:39:58
【问题描述】:

我有一个 Rails 模型对象,它的属性映射到数据库中的列。我计算了几个不在数据库列中的临时字段名称和年龄。有没有办法在不改变模型对象的情况下暂时将它们合并到对象中?

class MyModel < ApplicationRecord
end

我尝试使用 attributes.merge。并尝试过:

my_obj = my_obj.attributes.merge({ age: compute_age })

my_obj = my_obj.attributes.merge({ name: compute_name })

但是第二次合并失败,出现 NoMethodError: undefined method `attributes' for #Hash:0x0000000120060010。

看起来当我合并第一个对象时,它使对象成为哈希。所以我需要做

my_obj = my_obj.attributes.merge({ age: compute_age })

my_obj[:name]=compute_name

所有其他属性也作为散列访问。 然而,这对我来说感觉不一致和奇怪!

有没有比使用 attributes.merge 更好的选择,即保留对象? 我想将 attr 添加到模型对象可能更简洁,但这些属性是临时的,不应在外部访问。

【问题讨论】:

  • 所以我有一个序列化程序,它在序列化时间之前已经为我创建了临时哈希,但我需要将一个对象传递给它。这就是为什么临时哈希再次感觉有点多余的原因?我想在这种情况下向模型添加 attr_accessor 不会很糟糕?

标签: ruby-on-rails ruby object hash


【解决方案1】:

只要您调用 .attributes,您就会将 MyModel 实例转换为哈希。

要将其转回模型,您只需将该哈希传递给 MyModel 构造函数(假设您有一个 attr_accessor 用于虚拟属性):

my_obj = MyModel.new(my_obj.attributes.merge(age: compute_age))
my_obj = MyModel.new(my_obj.attributes.merge(name: compute_name))

您还可以在此处查看其他选项:Rails update_attributes without save?

编辑

澄清一点。您可以通过.attributes 将模型实例转换为哈希。您可以使用Model.new(attributes_hash) 将其变回模型。虽然它是一个散列,但您可以设置任何您想要的键值 - 它只是一个散列。但是为了将其转换回模型实例,您需要确保所有哈希键对应于模型上的实际属性(无论是模式定义的持久属性,还是 attr_accessor 定义的虚拟属性)。

如果你只是想把它变成一个哈希并在那里添加多个任意键值,你可以通过一次合并来完成:

attrs = my_obj.attributes.merge({ age: compute_age, name: compute_name })

【讨论】:

  • 感谢您的快速回答!看起来像 assign_attributes 可能会解决问题,但我希望有一种方法,无需在模型中添加 attr_accessor: :name, :age :D 我猜构造函数也需要这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多