Rails update_nested_attributes。如果存在,请更新,如果不存在则创建?

时间:2017-06-22 00:18:39

标签: ruby-on-rails nested-attributes

假设我有两个表,treesapples以及一个联合表tree_apples。假设tree_apples表有几个重要的列,名为rotten(布尔值)和branch(int)。

在控制器中说trees,我有这个:

@tree.update_nested_attributes(tree_params)和我的tree_params方法如下所示:

tree_apple_params: {
    :apple_id,
    :rotten,
    :branch
}

假设我正在更新的树已经有一个id为3的tree_apple rotten: truebranches: nil,并且进入此控制器以更新分支的传入参数具有看起来像这样的参数:

tree_apple_params: [{
   apple_id: 3,
   rotten: nil,
   branch: 5
  },
  { 
   apple_id: 4,
   rotten: nil,
   branch: 6
  },
  ...
]

因此创建或更新一堆tree_apples是一种方式。 params来自的页面想要更新引用3 tree_apple的{​​{1}}的分支,对于此apple_id,它不提供有关腐烂状态的任何输入。我不想创建另一个引用tree_apple tree_apple的{​​{1}},其中apple_id: 3为rotten_state。我想更新现有的nil。所以,对于这个tree_apple,我想找到它,然后用分支5 更新它。但对于所有其他引用此树上不存在的苹果的参数,如果tree_apple不存在,我想创建tree_apples

有办法做到这一点吗?这个逻辑是作为某种回调属于控制器还是作为模型?

2 个答案:

答案 0 :(得分:0)

查看find_or_create_by

有些事情:

tree_params.each do |params|
    tree_apple = TreeApple.find_or_create_by(apple_id: params[:apple_id])
    tree_apple.update_attributes(branch: params[:branch], rotten: params[:rotten])
end

在您的控制器中。

答案 1 :(得分:0)

如果要更新它,则必须传递tree_apple记录的ID,例如

tree_apple_params: [{
 id: 1, #passing the id of the tree_apple record here will update existing records
 apple_id: 3,
 rotten: nil,
 branch: 5
},
{ #passing NO id here will create records
 apple_id: 4,
 rotten: nil,
 branch: 6
},
...
]

显然允许你的参数中的id:

tree_apple_params: {
    :id,
    :apple_id,
    :rotten,
    :branch
}