如何在更新父对应的属性后自动清除孤儿?

时间:2013-11-20 14:35:19

标签: sql ruby-on-rails ruby activerecord

我有一个用户模型(链接到S3)与之关联的图像

class User < ActiveRecord::Base
  has_many :images, :dependent => :destroy
  # left out other attributes for simplicity of the example
end

class Image < ActiveRecord::Base
  belongs_to :user
  attr_accessible :url, :name, :bucket
end

我有一个JSON API来更新图像(/ users /:id)。使用JSON正文的示例POST请求如下所示:

{
  "user": { 
    "images": [
        {
            "name":"Fun pic",
            "bucket":"pix3.mydomain.com"
        },
        {
            "name":"Hilarious pic",
            "bucket":"pix2.mydomain.com"
        }
    ]
  }
}

我想用这个新数组覆盖该用户的所有图像,而不会在数据库中留下旧图像的痕迹。

目前,我使用Image.create(hash)将数组中的所有图像哈希映射到Image对象。让我们调用结果数组'new_images'。然后我调用User.update_attributes({“images”=&gt; new_images})。用户现在将分配给他的正确图像,但之前的图像仍在数据库中浮动。

所以,我正在寻找一种简单的方法来替换新对象中has_many关联中的所有对象,而不会将旧对象留在数据库中。当然我可以创建一个事务,首先删除所有旧图像,然后分配新图像,但它看起来像很多样板。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我会尝试这种方法:

@user.images.destroy_all  #destroy all the images that were associated with the user
@user.images = new_images #set the new array of images
@user.save                #commit changes to the object

可能有点脏,但肯定会有效。

答案 1 :(得分:1)

这是Api dock

的文档
collection=objects

Replaces the collections content by deleting and adding objects as appropriate. If the :through option is true callbacks in the join models are triggered except destroy callbacks, since deletion is direct.

所以当你这样做时

user.images = new_images
user.save

这会破坏与用户关联的旧旧版本并在事务中更新new_images上的user_id