如何在内存中替换ActiveRecord关联成员,然后保存关联

时间:2018-01-26 20:11:46

标签: ruby-on-rails activerecord

我有一个has_may through关联,我正在尝试更改内存的关联记录,然后在一个事务中更新所有关联{ {1}}。我无法弄清楚如何使这项工作。

这是我正在做的事情的简化(使用流行的Blog示例):

#save

这有点做作。关键是如果用户添加的帖子已经存在于系统中,我们只需将现有帖子分配给他们。如果帖子尚不存在,我们会创建一个新帖子。

问题是,当我致电# The model class Users < ActiveRecord::Base has_many :posts, through: user_posts accepts_nested_attributes_for :posts end # The controller class UsersController < ApplicationController def update user.assign_attributes(user_params) replace_existing_posts(user) user.save end private def replace_existing_posts(user) user.posts.each do |post| existing = Post.find_by(title: post.title) next unless existing post.id = existing post.reload end end end 时,它会保存所有帖子(以及user.save关联),但不会创建user_post关联对于现有记录。

我尝试通过将user_post添加到has_many :user_posts, autosave: true模型来解决此问题,但尽管documented statement“当User为真时所有孩子都已保存”,并不反映我看到的行为。

我可以使用像这样的hacky来完成这项工作,但我不想单独保存关联记录(删除和替换所有关联会导致大量回调,我不想解雇)。 / p>

:autosave

我已经浏览了ActiveRecord文档和源代码,但没有找到将记录添加到在内存中创建映射记录的posts = user.posts.to_a user.posts.reset user.posts.replace(posts) 关联的方法。

1 个答案:

答案 0 :(得分:0)

我终于通过手动添加关联记录来实现这一点。

所以现在我的控制器也在更新中执行此操作:

user.posts.each do |post|
  next unless post.persisted?
  user.user_posts.build(post: post)
end

将此作为答案发布,除非有人有更好的解决方案。