我有两个模型用户和状态。状态嵌入在用户中:
用户.rb
class User
include Mongoid::Document
include Mongoid::Timestamps
embeds_one :status, as: :statusable
状态.rb
class Status
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :statusable, polymorphic: true
现在我正在尝试创建状态文档内部用户:
* 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
知道为什么会这样吗?
来自文档:
模型类名不能以"s"结尾,因为它将被视为 单词的复数形式。例如,状态将是 被认为是Statu的复数形式,这将导致一些已知的 问题。
因此,请尝试定义您与class_name
元数据的关系,迫使mongoid使用该类。
embeds_one :status, as: :statusable, class_name: "Status"
这里有几个问题。正如marquez所回答的那样,以"s"结尾的模型类名是有问题的,但可以通过class_name说明符进行寻址。如果你不需要多态性,那么你只需对用户#状态和用户#状态=使用自动生成的方法。但是对于多态性和class_name覆盖,"as:"说明符对我不起作用,但以下说明符有用。希望这能帮助你继续前进。
app/models/user.rb
class User
include Mongoid::Document
include Mongoid::Timestamps
embeds_one :statusable, class_name: "Status"
end
app/models/status.rb
class Status
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :statusable, polymorphic: true
end
test/unit/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
$ 耙子测试
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