Mongoid在Parent中创建嵌入式文档

时间:2013-11-04 10:13:46

标签: ruby-on-rails mongodb mongoid embedding database-relations

我有两种型号用户状态。 状态嵌入在用户中:

User.rb

class User

  include Mongoid::Document
  include Mongoid::Timestamps

  embeds_one :status, as: :statusable

Status.rb

class Status

  include Mongoid::Document
  include Mongoid::Timestamps

  embedded_in :statusable, polymorphic: true

现在我正在尝试创建状态Document Inside user:

* User.create!(:name =>'try',:status => {:num => '111'})
=> NameError: uninitialized constant Statu
    from /var/lib/gems/1.9.1/gems/activesupport-3.2.13/lib/active_support/inflector/methods.rb:230:in 'block in constantize'
    from /var/lib/gems/1.9.1/gems/activesupport-3.2.13/lib/active_support/inflector/methods.rb:229:in 'each'
    ....
    ....

* u = User.create!(:name =>'try')
u.status = Status.create!(:num => '222')
=> Mongoid::Errors::NoParent: 
Problem:
  Cannot persist embedded document Status without a parent document.
Summary:
  If the document is embedded, in order to be persisted it must always have a reference to its parent document. This is most likely caused by either calling Status.create or Status.create! without setting the parent document as an attribute.
Resolution:
  Ensure that you have set the parent relation if instantiating the embedded document direcly, or always create new embedded documents via the parent relation.

* u.status = {:num => '222'}
=> NameError: uninitialized constant Statu

知道为什么会这样吗?

2 个答案:

答案 0 :(得分:3)

来自文档:

  

模型类名称不能以“s”结尾,因为它将被视为   这个词的复数形式。例如,状态将是   被认为是Statu的复数形式,这将导致一些已知的   问题。

因此,尝试定义与class_name元数据的关系,强制mongoid使用该类。

embeds_one :status, as: :statusable, class_name: "Status"

答案 1 :(得分:2)

这里有几个问题。 正如marquez所回答的那样,以“s”结尾的模型类名称存在问题,但可通过class_name说明符进行寻址。 如果您不需要多态性,那么您只需将自动生成的方法用于User#status和User#status =。 但是由于多态性和class_name覆盖,“as:”说明符对我不起作用,但以下情况确实如此。 希望这有助于你继续前进。

应用程序/模型/ user.rb

class User
  include Mongoid::Document
  include Mongoid::Timestamps

  embeds_one :statusable, class_name: "Status"
end

应用程序/模型/ status.rb

class Status
  include Mongoid::Document
  include Mongoid::Timestamps

  embedded_in :statusable, polymorphic: true
end

测试/单元/ user_test.rb

require 'test_helper'
require 'pp'

class UserTest < ActiveSupport::TestCase
  def setup
    User.delete_all
  end

  test "basic embedding" do
    User.create!(:name =>'try',:statusable => {:num => '111'})
    assert_equal 1, User.count
    u = User.create!(:name =>'try')
    u.statusable = Status.new(:num => '222')
    assert_equal 2, User.count
    puts
    pp (User.all.to_a.collect{|user| user.serializable_hash})
  end
end

$ rake test

Run options:

# Running tests:

[1/1] UserTest#test_basic_embedding
[{"_id"=>"5277f5077f11bac4b4000001",
  "created_at"=>Mon, 04 Nov 2013 19:27:03 UTC +00:00,
  "name"=>"try",
  "statusable"=>
   {"_id"=>"5277f5077f11bac4b4000002",
    "created_at"=>nil,
    "num"=>"111",
    "updated_at"=>nil},
  "updated_at"=>Mon, 04 Nov 2013 19:27:03 UTC +00:00},
 {"_id"=>"5277f5077f11bac4b4000003",
  "created_at"=>Mon, 04 Nov 2013 19:27:03 UTC +00:00,
  "name"=>"try",
  "statusable"=>
   {"_id"=>"5277f5077f11bac4b4000004",
    "created_at"=>Mon, 04 Nov 2013 19:27:03 UTC +00:00,
    "num"=>"222",
    "updated_at"=>Mon, 04 Nov 2013 19:27:03 UTC +00:00},
  "updated_at"=>Mon, 04 Nov 2013 19:27:03 UTC +00:00}]
Finished tests in 0.044048s, 22.7025 tests/s, 45.4050 assertions/s.
1 tests, 2 assertions, 0 failures, 0 errors, 0 skips