在has_one belongs_to对象之间创建mongoid关系会引发错误

时间:2013-07-20 21:28:53

标签: ruby mongodb mongoid

我有这种关系:

class EmailType
  include Mongoid::Document
  include Mongoid::Timestamps
  has_one :job_status, :inverse_of => :email_type

class JobStatus
  include Mongoid::Document
  belongs_to :email_type, :inverse_of => :job_status

但是当我尝试创建它们之间的关系时,我得到一个错误。我的例子如下所示,我可以看到http://two.mongoid.org/docs/relations/referenced/1-1.html上指示的相同模式。

这对我来说是一个谜,是错误消息显示NameError: uninitialized constant JobStatu而非NameError: uninitialized constant JobStatus ......

Loading development environment (Rails 3.2.12)
2.0.0-p247 :001 > e = EmailType.new
 => #<EmailType _id: 51eafe9183c3366282000001, created_at: nil, updated_at: nil, name: nil, type: nil, value: nil, from: nil, subject: nil, line_break: "\n", order_id_line: nil, order_id_regex: nil, mail_address_line: nil, mail_address_regex: nil, name_line: nil, name_regex: nil, user_id: nil> 
2.0.0-p247 :002 > j = JobStatus.new
 => #<JobStatus _id: 51eafea583c3366282000002, group_id: nil, name: nil, status: "new", error_msg: "", extra: {}, email_type_id: nil> 
2.0.0-p247 :003 > e.job_status = j
NameError: uninitialized constant JobStatu
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.12/lib/active_support/inflector/methods.rb:230:in `block in constantize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.12/lib/active_support/inflector/methods.rb:229:in `each'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.12/lib/active_support/inflector/methods.rb:229:in `constantize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.12/lib/active_support/core_ext/string/inflections.rb:54:in `constantize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/metadata.rb:630:in `klass'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/proxy.rb:54:in `klass'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/referenced/one.rb:21:in `block in initialize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/proxy.rb:41:in `init'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/referenced/one.rb:20:in `initialize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:44:in `new'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:44:in `create_relation'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:26:in `__build__'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:269:in `block (2 levels) in setter'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:175:in `without_autobuild'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:263:in `block in setter'
from (irb):3
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/railties-3.2.12/lib/rails/commands/console.rb:47:in `start'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/railties-3.2.12/lib/rails/commands/console.rb:8:in `start'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/railties-3.2.12/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'2.0.0-p247 :004 > 

为了确保我没有把它混合起来,我试图反过来这样做:

Loading development environment (Rails 3.2.12)
2.0.0-p247 :001 > e = EmailType.new
 => #<EmailType _id: 51eaff9283c3365840000001, created_at: nil, updated_at: nil, name: nil, type: nil, value: nil, from: nil, subject: nil, line_break: "\n", order_id_line: nil, order_id_regex: nil, mail_address_line: nil, mail_address_regex: nil, name_line: nil, name_regex: nil, user_id: nil> 
2.0.0-p247 :002 > j = JobStatus.new
 => #<JobStatus _id: 51eaff9483c3365840000002, group_id: nil, name: nil, status: "new", error_msg: "", extra: {}, email_type_id: nil> 
2.0.0-p247 :003 > j.email_type = e
NameError: uninitialized constant JobStatu
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.12/lib/active_support/inflector/methods.rb:230:in `block in constantize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.12/lib/active_support/inflector/methods.rb:229:in `each'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.12/lib/active_support/inflector/methods.rb:229:in `constantize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.12/lib/active_support/core_ext/string/inflections.rb:54:in `constantize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/metadata.rb:630:in `klass'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/proxy.rb:54:in `klass'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/referenced/one.rb:21:in `block in initialize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/proxy.rb:41:in `init'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/referenced/one.rb:20:in `initialize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:44:in `new'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:44:in `create_relation'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:26:in `__build__'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:269:in `block (2 levels) in setter'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:175:in `without_autobuild'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:263:in `block in setter'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/extensions/object.rb:104:in `do_or_do_not'
... 5 levels...
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/proxy.rb:25:in `bind_one'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/referenced/in.rb:25:in `block in initialize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/proxy.rb:41:in `init'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/referenced/in.rb:23:in `initialize'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:44:in `new'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:44:in `create_relation'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:26:in `__build__'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:269:in `block (2 levels) in setter'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:175:in `without_autobuild'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/mongoid-3.1.3/lib/mongoid/relations/accessors.rb:263:in `block in setter'
from (irb):3
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/railties-3.2.12/lib/rails/commands/console.rb:47:in `start'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/railties-3.2.12/lib/rails/commands/console.rb:8:in `start'
from /Users/christoffer-jorgensen/.rvm/gems/ruby-2.0.0-p247/gems/railties-3.2.12/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'2.0.0-p247 :004 >

3 个答案:

答案 0 :(得分:4)

这是一个众所周知的Mongoid问题,described here in the official documentation

一种可能的解决方法是按照上述文件中的建议进行:

ActiveSupport::Inflector.inflections do |inflect|
  inflect.singular("jobstatus", "jobstatus")
end

或者接近那个。

答案 1 :(得分:2)

你正在使用ruby 2.0,我没有任何东西要检查它,但是为了帮助你,尝试一个更简单的名字,可能最终没有SStatu代替Status意味着当搜索特定模型时,mongoid会尝试使其变得单一。

你的模型听起来不错,你应该可以反过来做,所以试试e.job_status = j,看看它是否真的有效。

答案 2 :(得分:0)

更短的解决方案:

has_one :job_status, :inverse_of => :email_type, :class_name => "JobStatus"

更新:

@Ophion:我的意思是这应该有效:

class EmailType
  include Mongoid::Document
  include Mongoid::Timestamps
  has_one :job_status, :inverse_of => :email_type, :class_name => "JobStatus"

将class_name显式添加到关系中,以便Mongoid直接使用它,而无需单一化来获取模型名称。