Ruby/Rails class loading weirdness (possibly Thinking Sphinx related)
I've added two new models to my app (Rails 3.1 on 1.9.2-p180):
class MessageTemplateGroup < ActiveRecord::Base
options = { class_name: "MessageTemplate", foreign_key: "group_id" }
puts "*** In MessageTemplateGroup: #{options}"
has_many :templates, options
end
class MessageTemplate < ActiveRecord::Base
belongs_to :group, class_name: "MessageTemplateGroup", foreign_key: "group_id"
end
In the console, when I try MessageTemplateGroup.first.templates
, I get an error telling me that the column message_template_group_id
(what would be the default FK on message_templates
) doesn't exist in the database.
Running reload!
and then running the command again works fine.
I've narrowed the problem down to the fact that MessageTemplateGroup
is loaded twice, however, the second time it's loaded, the foreign_key is somehow ignored. The only difference is that thinking_sphinx (which I am using for completely separate models)
starts the load the second time, so maybe they're somehow overwriting Kernel#load? Indeed, if I remove all define_index calls in my code, the class is loaded correctly and only one time.
Here are the stack traces:
*** In MessageTemplateGroup: {:class_name=>"MessageTemplate", :foreign_key=>"group_id"}
*** ActiveRecord::Reflection:create_reflection: MessageTemplateGroup -> templates: {:class_name=>"MessageTemplate", :foreign_key=>"group_id", :extend=>[]}
.../activerecord-3.1.0/lib/active_record/reflection.rb:31:in `/'
.../activerecord-3.1.0/lib/active_record/reflection.rb:31:in `create_reflection'
.../activerecord-3.1.0/lib/active_record/associations/builder/association.rb:21:in `build'
.../activerecord-3.1.0/lib/active_record/associations/builder/collection_association.rb:23:in `build'
.../activerecord-3.1.0/lib/active_record/autosave_association.rb:127:in `build'
.../activerecord-3.1.0/lib/active_record/associations/builder/has_many.rb:10:in `build'
.../activerecord-3.1.0/lib/active_record/associations/builder/collection_association.rb:13:in `build'
.../activerecord-3.1.0/lib/active_record/associations.rb:1177:in `has_many'
/Users/Martin/Code/app/app/models/message_template_group.rb:4:in `<class:MessageTemplateGroup>'
/Users/Martin/Code/app/app/models/message_template_group.rb:1:in `<top (required)>'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:456:in `load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:456:in `block in load_file'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:640:in `new_constants_in'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:455:in `load_file'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:342:in `require_or_load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:489:in `load_missing_constant'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:181:in `block in const_missing'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `each'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `const_missing'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:501:in `load_missing_constant'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:181:in `block in const_missing'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `each'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `const_missing'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:501:in `load_missing_constant'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:181:in `block in const_missing'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `each'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `const_missing'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:501:in `load_missing_constant'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:181:in `block in const_missing'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `each'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `const_missing'
.../activerecord-3.1.0/lib/active_record/reflection.rb:28:in `create_reflection'
.../activerecord-3.1.0/lib/active_record/associations/builder/association.rb:21:in `build'
.../activerecord-3.1.0/lib/active_record/autosave_association.rb:127:in `build'
.../activerecord-3.1.0/lib/active_record/associations/builder/belongs_to.rb:14:in `build'
.../activerecord-3.1.0/lib/active_record/associations/builder/association.rb:12:in `build'
.../activerecord-3.1.0/lib/active_record/associations.rb:1409:in `belongs_to'
/Users/Martin/Code/app/app/models/user.rb:3:in `<class:User>'
/Users/Martin/Code/app/app/models/user.rb:2:in `<top (required)>'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:456:in `load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:456:in `block in load_file'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:640:in `new_constants_in'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:455:in `load_file'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:342:in `require_or_load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:489:in `load_missing_constant'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:181:in `block in const_missing'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `each'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `const_missing'
/Users/Martin/Code/app/test/factories/factories.rb:55:in `<top (required)>'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:234:in `load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:234:in `block in load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:223:in `block in load_dependency'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:640:in `new_constants_in'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:223:in `load_dependency'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:234:in `load'
.../factory_girl-2.0.5/lib/factory_girl/find_definitions.rb:20:in `block (2 levels) in find_definitions'
.../factory_girl-2.0.5/lib/factory_girl/find_definitions.rb:19:in `each'
.../factory_girl-2.0.5/lib/factory_girl/find_definitions.rb:19:in `block in find_definitions'
.../factory_girl-2.0.5/lib/factory_girl/find_definitions.rb:15:in `each'
.../factory_girl-2.0.5/lib/factory_girl/find_definitions.rb:15:in `find_definitions'
.../factory_girl_rails-1.1.0/lib/factory_girl_rails/railtie.rb:11:in `block in <class:Railtie>'
.../activesupport-3.1.0/lib/active_support/lazy_load_hooks.rb:34:in `call'
.../activesupport-3.1.0/lib/active_support/lazy_load_hooks.rb:34:in `execute_hook'
.../activesupport-3.1.0/lib/active_support/lazy_load_hooks.rb:43:in `block in run_load_hooks'
.../activesupport-3.1.0/lib/active_support/lazy_load_hooks.rb:42:in `each'
.../activesupport-3.1.0/lib/active_support/lazy_load_hooks.rb:42:in `run_load_hooks'
.../railties-3.1.0/lib/rails/application/finisher.rb:56:in `block in <module:Finisher>'
.../railties-3.1.0/lib/rails/initializable.rb:25:in `instance_exec'
.../railties-3.1.0/lib/rails/initializable.rb:25:in `run'
.../railties-3.1.0/lib/rails/initializable.rb:50:in `block in run_initializers'
.../railties-3.1.0/lib/rails/initializable.rb:49:in `each'
.../railties-3.1.0/lib/rails/initializable.rb:49:in `run_initializers'
.../railties-3.1.0/lib/rails/application.rb:92:in `initialize!'
.../railties-3.1.0/lib/rails/railtie/configurable.rb:30:in `method_missing'
/Users/Martin/Code/app/config/environment.rb:5:in `<top (required)>'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:240:in `require'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:240:in `block in require'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:223:in `block in load_dependency'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:640:in `new_constants_in'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:223:in `load_dependency'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:240:in `require'
.../railties-3.1.0/lib/rails/application.rb:78:in `require_environment!'
.../railties-3.1.0/lib/rails/commands.rb:39:in `<top (required)>'
script/rails:6:in `require'
script/rails:6:in `<main>'
Start of second load (note that "In MessageTemplateGroup" wasn't logged):
*** ActiveRecord::Reflection:create_reflection: MessageTemplateGroup -> templates: {:class_name=>"MessageTemplate", :extend=>[]}
.../activerecord-3.1.0/lib/active_record/reflection.rb:31:in `/'
.../activerecord-3.1.0/lib/active_record/reflection.rb:31:in `create_reflection'
.../activerecord-3.1.0/lib/active_record/associations/builder/association.rb:21:in `build'
.../activerecord-3.1.0/lib/active_record/associations/builder/collection_association.rb:23:in `build'
.../activerecord-3.1.0/lib/active_record/autosave_association.rb:127:in `build'
.../activerecord-3.1.0/lib/active_record/associations/builder/has_many.rb:10:in `build'
.../activerecord-3.1.0/lib/active_record/associations/builder/collection_association.rb:13:in `build'
.../activerecord-3.1.0/lib/active_record/associations.rb:1177:in `has_many'
/Users/Martin/Code/app/app/models/message_template_groups.rb:2:in `<class:MessageTemplateGroup>'
/Users/Martin/Code/app/app/models/message_template_groups.rb:1:in `<top (required)>'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:456:in `load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:456:in `block in load_file'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:640:in `new_constants_in'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:455:in `load_file'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:342:in `require_or_load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:489:in `load_missing_constant'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:181:in `block in const_missing'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `each'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `const_missing'
.../activesupport-3.1.0/lib/active_support/inflector/methods.rb:124:in `block in constantize'
.../activesupport-3.1.0/lib/active_support/inflector/methods.rb:123:in `each'
.../activesupport-3.1.0/lib/active_support/inflector/methods.rb:123:in `constantize'
.../activesupport-3.1.0/lib/active_support/core_ext/string/inflections.rb:43:in `constantize'
.../bundler/gems/thinking-sphinx-39f6dd65e94b/lib/thinking_sphinx/context.rb:64:in `block (2 levels) in load_models'
.../bundler/gems/thinking-sphinx-39f6dd65e94b/lib/thinking_sphinx/context.rb:54:in `each'
.../bundler/gems/thinking-sphinx-39f6dd65e94b/lib/thinking_sphinx/context.rb:54:in `block in load_models'
.../bundler/gems/thinking-sphinx-39f6dd65e94b/lib/thinking_sphinx/context.rb:53:in `each'
.../bundler/gems/thinking-sphinx-39f6dd65e94b/lib/thinking_sphinx/context.rb:53:in `load_models'
.../bundler/gems/thinking-sphinx-39f6dd65e94b/lib/thinking_sphinx/context.rb:15:in `prepare'
.../bundler/gems/thinking-sphinx-39f6dd65e94b/lib/thinking_sphinx.rb:81:in `block in context'
<internal:prelude>:10:in `synchronize'
.../bundler/gems/thinking-sphinx-39f6dd65e94b/lib/thinking_sphinx.rb:78:in `context'
.../bundler/gems/thinking-sphinx-39f6dd65e94b/lib/thinking_sphinx/active_record.rb:162:in `define_index'
/Users/Martin/Code/app/app/models/profile.rb:31:in `<class:Profile>'
/Users/Martin/Code/app/app/models/profile.rb:1:in `<top (required)>'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:456:in `load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:456:in `block in load_file'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:640:in `new_constants_in'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:455:in `load_file'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:342:in `require_or_load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:489:in `load_missing_constant'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:181:in `block in const_missing'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `each'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:179:in `const_missing'
/Users/Martin/Code/app/test/factories/factories.rb:177:in `<top (required)>'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:234:in `load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:234:in `block in load'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:223:in `block in load_dependency'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:640:in `new_constants_in'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:223:in `load_dependency'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:234:in `load'
.../factory_girl-2.0.5/lib/factory_girl/find_definitions.rb:20:in `block (2 levels) in find_definitions'
.../factory_girl-2.0.5/lib/factory_girl/find_definitions.rb:19:in `each'
.../factory_girl-2.0.5/lib/factory_girl/find_definitions.rb:19:in `block in find_definitions'
.../factory_girl-2.0.5/lib/factory_girl/find_definitions.rb:15:in `each'
.../factory_girl-2.0.5/lib/factory_girl/find_definitions.rb:15:in `find_definitions'
.../factory_girl_rails-1.1.0/lib/factory_girl_rails/railtie.rb:11:in `block in <class:Railtie>'
.../activesupport-3.1.0/lib/active_support/lazy_load_hooks.rb:34:in `call'
.../activesupport-3.1.0/lib/active_support/lazy_load_hooks.rb:34:in `execute_hook'
.../activesupport-3.1.0/lib/active_support/lazy_load_hooks.rb:43:in `block in run_load_hooks'
.../activesupport-3.1.0/lib/active_support/lazy_load_hooks.rb:42:in `each'
.../activesupport-3.1.0/lib/active_support/lazy_load_hooks.rb:42:in `run_load_hooks'
.../railties-3.1.0/lib/rails/application/finisher.rb:56:in `block in <module:Finisher>'
.../railties-3.1.0/lib/rails/initializable.rb:25:in `instance_exec'
.../railties-3.1.0/lib/rails/initializable.rb:25:in `run'
.../railties-3.1.0/lib/rails/initializable.rb:50:in `block in run_initializers'
.../railties-3.1.0/lib/rails/initializable.rb:49:in `each'
.../railties-3.1.0/lib/rails/initializable.rb:49:in `run_initializers'
.../railties-3.1.0/lib/rails/application.rb:92:in `initialize!'
.../railties-3.1.0/lib/rails/railtie/configurable.rb:30:in `method_missing'
/Users/Martin/Code/app/config/environment.rb:5:in `<top (required)>'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:240:in `require'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:240:in `block in require'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:223:in `block in load_dependency'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:640:in `new_constants_in'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:223:in `load_dependency'
.../activesupport-3.1.0/lib/active_support/dependencies.rb:240:in `require'
.../railties-3.1.0/lib/rails/application.rb:78:in `require_envir开发者_运维百科onment!'
.../railties-3.1.0/lib/rails/commands.rb:39:in `<top (required)>'
script/rails:6:in `require'
script/rails:6:in `<main>'
Is there anything forcibly loading this model (or any other model with a define_index block) in config/application.rb
or elsewhere?
Sublime Text 2 has some strange functionality surrounding renaming of files. When a file is renamed, the editor is not associated with the new file, so saving the file actually results in a duplicate file being created with the original file name. Since I accidentally generated the model with a plural name, I had a message_template_groups.rb
file, which I then renamed to message_template_group.rb
, saved and had the plural file re-created. Both files defined MessageTemplateGroup
and had the has_many
, but only the singular had the foreign_key
attribute.
This was a pretty dumb mistake but points to the fact that in ThinkingSphinx::Context#load_models
suppresses LoadError
and NameError
, which would have quickly caught my mistake. Time to go file some bug reports!
精彩评论