添加和使用嵌套属性

问题描述:

在轨道4应用程序,我有两个型号删除现有机型的的has_many关系:添加和使用嵌套属性

class Gallery 
    include Mongoid::Document 

    has_many :thumbnails 
end 

class Thumbnail 
    include Mongoid::Document 

    belongs_to :gallery 
end 

我与他们的缩略图和一些未使用的缩略图填充的MongoDB数据库与一群画廊(没有gallery_id)。

现在在客户端我用木偶与骨干,协会和我所代表的画廊像这样:

class Entities.Gallery extends Backbone.AssociatedModel 
    idAttribute: '_id' 
    urlRoot: '/galleries' 
    paramRoot: 'gallery' 

    relations: [ 
    type: Backbone.Many 
    key: 'thumbnails' 
    remoteKey: 'thumbnails_attributes' 
    relatedModel: -> Entities.Thumbnail              
    ] 

    initialize: ->                
    @on 'add:thumbnails', (thumbnail) => thumbnail.set 'gallery_id', @get('_id') 

class Entities.Thumbnail extends Backbone.AssociatedModel 
    idAttribute: '_id' 

但我也有未使用的缩略图的集合:

class Entities.UnusedThumbnails extends Backbone.Collection 
    model: Entities.Thumbnail 

    initialize: -> 
    @on 'add', (thumbnail) -> thumbnail.set 'gallery_id', null 

我可以在画廊和UnusedThumbnails集合之间移动缩略图很好,但我如何坚持它们?

如果我刚刚从UnusedThumbnails集合添加缩略图画廊缩略图和使用节省空间:

gallery.save([], patch: true) 

我得到一个404回应说:“文件(S)未找到类缩略图,ID( s)...“这是有道理的,因为rails只在画廊内搜索带有此id的缩略图。

同样用于从图库中删除缩略图,如果我张贴缺少缩略图的图库,则rails更新方法将假定这些缩略图保持不变。

是否需要分别保存每个添加/删除的缩略图?

这样做的正确方法是什么?

编辑: 我知道我可能会需要建立一个专门的更新动作,像update_strict(缺乏一个更好的名字)

def update_strict 
    new_ids = gallery_params[:thumbnails_attributes].map(&:_id) 
    existing_ids = @gallery.thumbnails_ids 

    ids_to_add = new_ids - existing_ids 
    ids_to_remove = existing_ids - new_ids 

    @gallery.thumbnails.find(ids_to_remove).each |thumbnail| do 
    thumbnail.gallery = nil 
    thumbnail.save 
    end 

    ids_to_add.each |id| do 
    thumbnail = Thumbnail.find(id) 
    thumbnail_params = (gallery_params[:thumbnails_attributes].select { |t| t._id == id })[0] 
    thumbnail.update(thumbnail_params) 
    end 

    gallery_params[:thumbnails_attributes].delete_if { |thumbnail| ids_to_add.include?(thumbnail._id) } 

    respond_to do |format| 
    if @gallery.update(gallery_params) 
     format.html { redirect_to @gallery, notice: 'Gallery was successfully updated.' } 
     format.json { head :no_content } 
    else 
     format.html { render action: 'edit' } 
     format.json { render json: @gallery.errors, status: :unprocessable_entity } 
    end 
    end 
end 

但有一个正确的,更清洁的方式?

我终于结束了在画廊模式覆盖thumbnails_attributes=

def thumbnails_attributes=thumbnails_attributes) 
    ids = thumbnails_attributes.map { |t| t['id'] } 
    (ids - thumbnail_ids).each do |id| 
    thumbnail = Thumbnail.find id 
    thumbnails << thumbnail 
    end 
    super(thumbnails_attributes) 
end 

这让我现有的缩略图自动添加到库中。 允许它们移除的最简单方法是切换到backbone-nested-attributes,它将_destroy属性添加到销毁的模型。