【问题标题】:Saving records recursively with Mongoid, Ancestry使用 Mongoid、Ancestry 递归保存记录
【发布时间】:2013-05-24 10:56:04
【问题描述】:

我有一个模型 Line Items 嵌入在 Line 模型中。在 Line create 视图中,我提供了定义多个嵌套级别的订单项的能力。

这是param[:line]的随机截图:

=> {"title"=>"Hello", "type"=>"World", "line_items"=>{"1"=>{"name"=>"A", 
    "position"=>"1", "children"=>{"1"=>{"name"=>"A1", "position"=>"1", 
    "children"=>{"1"=>{"name"=> "A11", "position"=>"1"}, "2"=>{"name"=>"A12",
    "position"=>"2"}}}, "2"=>{"name"=>"A2", "position"=>"2"}}}, "3"=>
    {"name"=>"B", "position"=>"3"}}}

在 Line#create 中,我有:

def create
  @line = Line.new(params[:line])

  if @line.save
    save_lines(params[:line][:line_items])
    flash[:success] = "Line was successfully created."
    redirect_to line_path 
  else
    render :action => "new"
  end
end

在 Line#save_lines 中,我有:

# Save children up to fairly infinite nested levels.. as much as it takes!
def save_lines(parent)
  unless parent.blank?
    parent.each do |i, values|
      new_root = @line.line_items.create(values)
      unless new_root[:children].blank?
        new_root[:children].each do |child|
          save_lines(new_root.children.create(child))
        end
      end
    end
  end
end

LineItem 模型如下所示:

class LineItem
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Ancestry
  has_ancestry

  # Fields
  field :name,        type: String,
  field :type,        type: String
  field :position,    type: Integer
  field :parent_id,   type: Moped::BSON::ObjectId

  attr_accessible :name, :type, :url, :position, :parent_id

  # Associations
  embedded_in :line, :inverse_of => :line_items
end

在 Line 模型中,我有:

# Associations
embeds_many :line_items, cascade_callbacks: true

按预期工作。但是,有没有更好的方法来使用 Ancestry 递归地保存 line_items?

【问题讨论】:

  • 我几天前解决了这个问题。递归创建对象的需求非常相似。但是您是否还需要将内部对象与外部对象关联(has_many)?就我而言,它们是必需的。
  • No 内部对象没有关联。实际上我将它的关联规范化以形成一个平面文档(表格)。
  • 查看有关递归嵌入的 Mongoid 文档:mongoid.org/en/mongoid/docs/relations.html 您根本不需要为此使用 Ancestry。这是accepts_nested_attributes_for 的文档:mongoid.org/en/mongoid/docs/nested_attributes.html 这使您的 Line 模型的参数散列能够包含您的嵌入式订单项,并自动创建对象。 (也可用于 ActiveRecord,仅供参考)

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


【解决方案1】:

我认为您的代码看起来不错。我只是重构了它。 怎么样:

def save_lines(parent)
  parent.each do |i, values|
    #get children hash if any
    children = values.delete("children")
    # create the object with whatever remain in values hash
    @line.line_items.create(values)
    # recurse if children isn't empty
    save_lines(children) if children
  end
end

【讨论】:

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