首页 > 解决方案 > Rails 中的嵌套属性,它们的键是列字段

问题描述

我有一个 Ruby on Rails 项目,其中有一个模型接受另一个模型的嵌套属性。我没有从标准表单接收输入 JSON,而是从具有特定格式的库接收。

假设我的数据库如下所示:

user columns: id, name, country
user_setting columns: key, value, user_id

我收到的输入如下所示:

{
  name: "name",
  country: "country",
  settings: {
     edit: true,
     autosave: false
  }
}

我可以通过执行以下操作将设置作为嵌套属性访问:

alias_attribute :settings, :settings_attributes

但现在的问题是设置字段被读取为一个["edit", "true"]无法保存到数据库的数组。

有什么方法可以配置模型以接受此输入并将键解释为key列,将值解释为value列?

我已经考虑重组整个输入以匹配 Rails 的预期,但这似乎是额外的工作(对我和服务器而言)并且有点混乱。

标签: ruby-on-railsnested-attributes

解决方案


不,这在 的行为中不受支持accepts_nested_attributes_for,并且 AFAIK 无法将其配置为以这种方式工作。您可以定义一个“虚拟方法”来接受手动设置预期accepts_nested_attributes_for样式的设置哈希:

def settings=(hash)
  self.settings_attributes = hash.map do |key, value|
    {
      id: user_settings.find_by(key: key)&.id # update any existing user_settings instead of duplicating
      key: key,
      value: value
    }
  end
end

这会将关联的 UserSetting 记录标记为脏,然后在您声明后自动保存accepts_nested_attributes_for。这里有很多魔法,所以你可能想要平衡所需的聪明/框架知识和可维护性。从长远来看,编写一个“愚蠢”的解决方案可能会更好。


推荐阅读