更新/销毁MongoMapper中的EmbeddedDocuments

时间:2012-07-04 16:11:21

标签: mongomapper

我似乎无法弄清楚如何在MongoMapper中更新或销毁EmbeddedDocuments。通过谷歌搜索我已经看到了不同的方法,如delete_if {}和其他方法,但似乎没有一个方法在语义上适用于我。 MongoMapper内置了什么内容来帮助解决这个问题吗?

class Schedule
  include MongoMapper::Document

  key :name, String
  key :description, String
  key :active, Boolean, :default => false

  many :periods

  validates_presence_of :name

  def activate!
    set({:active => true}, :active => false)

    self.active = true
  end
end

class Period
  include MongoMapper::EmbeddedDocument

  key :number, Integer
  key :text, String
  key :start, Time
  key :finish, Time

  embedded_in :schedule

  before_validation :number!

  validates_presence_of :number
  validates_presence_of :text
  validates_presence_of :start
  validates_presence_of :finish

  validates_format_of :start, :with => /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$/
  validates_format_of :finish, :with => /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$/

  def number!
    unless self.number
      number = schedule.periods.count + 1
    end
  end
end

1 个答案:

答案 0 :(得分:1)

以下测试显示了有关如何以两种方式更新和删除嵌入式文档的示例: (1)通过Ruby使用标准的数组访问器和方法,以及 (2)通过Mongo(MongoMapper / MongoDB)更新和删除数据库服务器上的嵌入文档

参考文献:

http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-delete_if
http://mongomapper.com/documentation/plugins/modifiers.html#set
http://www.mongodb.org/display/DOCS/Updating#Updating-%24set

请注意包含'。'的哈希键需要使用旧的(=>)语法。希望这会有所帮助。

测试/单元/ period_test.rb

require 'test_helper'

def ppp(obj)
  puts obj.inspect.gsub(/(, |\[)#/, "\\1\n #")
end

class PeriodTest < ActiveSupport::TestCase
  def setup
    Schedule.delete_all
    @today = Time.now.midnight
  end

  test "update and remove embedded documents" do
    schedule = Schedule.create(name: 'George')
    assert_equal(1, Schedule.count)
    schedule.periods << Period.new(number: 1, text: 'period 1', start: @today + 8.hours, finish: @today + 9.hours)
    schedule.periods << Period.new(number: 2, text: 'period 2', start: @today + 9.hours, finish: @today + 10.hours)
    schedule.periods << Period.new(number: 3, text: 'period 3', start: @today + 10.hours, finish: @today + 11.hours)
    schedule.periods.last.finish = @today + 12.hours #update in Ruby
    schedule.save
    assert_equal(1, Schedule.count)
    puts "schedule with three periods --------"
    ppp Schedule.first
    schedule.periods.delete_if {|period| period.text == 'period 2'} #remove in Ruby
    schedule.save
    puts "schedule after removing period 2 in Ruby --------"
    ppp Schedule.first
    Schedule.set( {name: 'George', 'periods.text' => 'period 1'}, {'periods.$.finish' => @today + 10.hours} ) #update embedded document in MongoDB
    puts "schedule after updatting period 1 via Mongo --------"
    ppp Schedule.first
    Schedule.pull( {name: 'George'}, { periods: { text: 'period 1'} } ) #remove embedded document in MongoDB
    puts "schedule after pulling period 1 via Mongo --------"
    ppp Schedule.first
  end
end

输出

Run options: --name=test_update_and_remove_embedded_documents

# Running tests:

schedule with three periods --------
#<Schedule _id: BSON::ObjectId('4ff732e77f11ba6fe9000001'), active: false, name: "George", periods: [
 #<Period _id: BSON::ObjectId('4ff732e77f11ba6fe9000002'), finish: Fri, 06 Jul 2012 13:00:00 UTC +00:00, number: 1, start: Fri, 06 Jul 2012 12:00:00 UTC +00:00, text: "period 1">,
 #<Period _id: BSON::ObjectId('4ff732e77f11ba6fe9000003'), finish: Fri, 06 Jul 2012 14:00:00 UTC +00:00, number: 2, start: Fri, 06 Jul 2012 13:00:00 UTC +00:00, text: "period 2">,
 #<Period _id: BSON::ObjectId('4ff732e77f11ba6fe9000004'), finish: Fri, 06 Jul 2012 16:00:00 UTC +00:00, number: 3, start: Fri, 06 Jul 2012 14:00:00 UTC +00:00, text: "period 3">]>
schedule after removing period 2 in Ruby --------
#<Schedule _id: BSON::ObjectId('4ff732e77f11ba6fe9000001'), active: false, name: "George", periods: [
 #<Period _id: BSON::ObjectId('4ff732e77f11ba6fe9000002'), finish: Fri, 06 Jul 2012 13:00:00 UTC +00:00, number: 1, start: Fri, 06 Jul 2012 12:00:00 UTC +00:00, text: "period 1">,
 #<Period _id: BSON::ObjectId('4ff732e77f11ba6fe9000004'), finish: Fri, 06 Jul 2012 16:00:00 UTC +00:00, number: 3, start: Fri, 06 Jul 2012 14:00:00 UTC +00:00, text: "period 3">]>
schedule after updatting period 1 via Mongo --------
#<Schedule _id: BSON::ObjectId('4ff732e77f11ba6fe9000001'), active: false, name: "George", periods: [
 #<Period _id: BSON::ObjectId('4ff732e77f11ba6fe9000002'), finish: Fri, 06 Jul 2012 14:00:00 UTC +00:00, number: 1, start: Fri, 06 Jul 2012 12:00:00 UTC +00:00, text: "period 1">,
 #<Period _id: BSON::ObjectId('4ff732e77f11ba6fe9000004'), finish: Fri, 06 Jul 2012 16:00:00 UTC +00:00, number: 3, start: Fri, 06 Jul 2012 14:00:00 UTC +00:00, text: "period 3">]>
schedule after pulling period 1 via Mongo --------
#<Schedule _id: BSON::ObjectId('4ff732e77f11ba6fe9000001'), active: false, name: "George", periods: [
 #<Period _id: BSON::ObjectId('4ff732e77f11ba6fe9000004'), finish: Fri, 06 Jul 2012 16:00:00 UTC +00:00, number: 3, start: Fri, 06 Jul 2012 14:00:00 UTC +00:00, text: "period 3">]>
.

Finished tests in 0.038952s, 25.6726 tests/s, 51.3452 assertions/s.

1 tests, 2 assertions, 0 failures, 0 errors, 0 skips