【问题标题】:Replace embedded documents on save in Mongoid在 Mongoid 中保存时替换嵌入的文档
【发布时间】:2012-09-21 11:45:54
【问题描述】:

我希望能够在保存时替换 MongoDB 对象中的整个嵌入文档集 - HTML 表单将包含整个新集合。

我还希望它在保存之前验证所有内容 - 即不要丢弃旧文档,然后在添加时验证每个文档。

我想出了一个实现,但它并没有持续存在 - 没有一个新的嵌入文档出现。一个额外的复杂性是涉及到继承。这是(简化的)我到目前为止的模型集:

class Person
  include Mongoid::Document
  embeds_many :vehicles
end

class Vehicle 
  include Mongoid::Document
  embedded_in :person
end

class Car < Vehicle
end

class Motorbike < Vehicle
end

为了弄清楚当用户提交表单时要实例化什么样的车辆,我在 Person 类中添加了这个方法:

def build_from_hash(hash)
   @vehicles= []
   hash.each do |idx, vehicle|
      if vehicle[:_type].constantize < Inclusion # Check for inheritance, for security
         self.vehicles.push vehicle[:_type].constantize.new(vehicle)
      end
   end
end

并修改控制器来调用它:

def submit_build
  @person= current_user.persons.find(params[:id])
  @person.build_from_hash(params[:vehicles]) if params.has_key? :vehicles

  respond_to do |format|
    if @person.save # Also tried: @person.update_attributes(inclusions: @person.vehicles)
      format.html { redirect_to @person, notice: 'Person was successfully updated.' }
      format.json { head :no_content }
    else
      format.html { render action: "build" }
      format.json { render json: @person.errors, status: :unprocessable_entity }
    end
  end
end

没有产生错误 - 页面重定向就像它已经工作一样,但是当我再次检查它时没有嵌入文档。

使用 Rails 3.2.8、Mongoid 3.0.5、MongoDB 1.8.3。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 mongoid


    【解决方案1】:

    我想出了如何以更标准的 Rails 式方式来做到这一点,尽管有一些特殊行为的解决方法。

    简短回答:Person 类需要accepts_nested_attributes_for :vehicles,我必须从控制器中删除所有自定义内容,将操作替换为标准更新操作。但是它不会接受 Vehicle 子类的 _type 参数,除非 Rails 进程已经实例化了每个子类的对象,所以我不得不使用这样的初始化程序来解决它:

    Car.new
    Motorbike.new
    

    长答案是on the Mongoid Google group

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多