为了简化我的情况,我有一个模块,当我的Rails应用程序初始化时,它被加载到Mongoid :: Document中:
Mongoid::Document.send(:include, ActiveRecordBridge)
该模块定义了一种方法:
def has_many_records(*records)
options = records.extract_options!
if options[:polymorphic]
class_eval <<-EOS
def #{ record }
@#{ record } ||= #{ record.to_s.singularize.classify.constantize }.where( document_id: String(id), document_type: self.class.name)
end
EOS
end
end
现在我的Mongoid课程使用它:
class Something
include Mongoid::Document
has_many_records :something_else, polymorphic: true
end
这很有效,但是另一位开发人员将sync gem添加到我的系统中,并在SomethingElse类中使用了它:
class SomethingElse < ActiveRecord::Base
sync :all
end
一旦启动Rails应用程序,我就会遇到以下异常:
Uncaught exception: undefined method `sync' for #<Class:0x007fb7910530c0>
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activerecord-4.1.5/lib/active_record/dynamic_matchers.rb:26:in `method_missing'
/Users/donato/projects/core revisions/core/app/models/something_else.rb:73:in `<class:Task>'
/Users/donato/projects/core revisions/core/app/models/something_else.rb:19:in `<top (required)>'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:443:in `load'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:443:in `block in load_file'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:633:in `new_constants_in'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:442:in `load_file'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:342:in `require_or_load'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:480:in `load_missing_constant'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:180:in `const_missing'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/inflector/methods.rb:238:in `const_get'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/inflector/methods.rb:238:in `block in constantize'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/inflector/methods.rb:236:in `each'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/inflector/methods.rb:236:in `inject'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/inflector/methods.rb:236:in `constantize'
/Users/donato/.rvm/gems/ruby-2.1.2@core/gems/activesupport-4.1.5/lib/active_support/core_ext/string/inflections.rb:66:in `constantize'
/Users/donato/projects/core revisions/core/lib/active_record_bridge.rb:55:in `block in has_many_records'
这是有趣的部分。当我用一个块替换class_eval的字符串参数时,错误消失了:
class_eval do
def something_elses
@something_elses ||= SomethingElse.where(document_id: String(id), document_type: self.class.name)
end
end
虽然这有效,但这不是我想要的,因为现在我明确地写了something_else而不是使用字符串插值。
我的问题:导致此错误的字符串参数怎么样,而block参数不会?
答案 0 :(得分:0)
当您传入字符串参数时,您正在插入record.to_s.singularize.classify.constantize
。对constantize
的最后一次调用会尝试查找常量SomethingElse
。开发中的Rails应用程序通常设置为懒惰地加载它们的类,所以只有在这一点上app才会尝试加载包含SomethingElse
的文件,因为文件包含加载时遇到的错误。
在第二种情况下,在您实际调用SomethingElse
之前未达到对something_elses
的引用,这意味着只有在此时才会加载文件并遇到错误。你可以尝试启动一个控制台并调用该方法或只输入SomethingElse
- 两者都应该引发错误。