我有一个问题,在我的ruby on rails应用程序中使用的动态查找器几乎总是可以工作,但是很少会抛出nomethoderror。
以下是发生错误时的异常堆栈的副本:
2013-10-16 05:34:04.723 [Rails/26343 ] :
NoMethodError (undefined method `find_by_id' for #<Class:0xa972ef8>):
app/models/sas_ui/supergroup_instance.rb:394:in `event_by_id'
app/models/trace.rb:73:in `event_by_id'
app/controllers/tview_controller.rb:102:in `select_event'
lib/tview_logging_control.rb:22:in `call'
引发异常的代码(supergroup_instance第394行):
event = SasUi::Event.find_by_id(event_db_id)
event是sasui的一个子类,它是activerecord::base的一个子类。
以下是数据库条目:
Table "public.events"
Column | Type | Modifiers
------------+-----------------------------+---------------------------------------
id | integer | not null default nextval('events_id_seq'::regclass)
sg_inst_id | integer | not null
sas_id | integer | not null
system_id | integer |
trail_id | bigint |
event_id | integer |
time | timestamp without time zone |
sqn | bigint |
instance | integer |
data | bytea |
Indexes:
"events_pkey" PRIMARY KEY, btree (id)
"index_events_on_sg_inst_id" btree (sg_inst_id)
Foreign-key constraints:
"events_sg_inst_id_fk" FOREIGN KEY (sg_inst_id) REFERENCES supergroup_instances(id) ON DELETE CASCADE
这是99.99%的工作时间,我们有几百个客户使用这个软件,但非常偶然,一个客户看到这个问题。从应用程序注销并重新登录似乎可以解决问题。
应用程序中有多个线程访问这些模型,这是另一种可能的探索途径。
据我所知,动态查找器的工作方式是重写缺少方法的方法,并在字符上拆分被调用方法的名称以提取请求的属性名称。如果提取的属性存在于模型中的属性名中,则将进行查询,否则将抛出原始的nomethoderro。
属性名称包含以下文档:
如果列名数组不是抽象的,则将其作为字符串返回
类和表存在。否则返回空数组。
除了上面列出的异常之外,postgres日志或应用程序日志中没有提示条目。
我最初的想法是,可能存在一些间歇性的数据库问题,postgres出于某种原因报告表不存在。重新启动应用程序不会重新启动数据库,但会解决问题。
我想知道它是否也可以归结为rails缓存表,而这个缓存不知何故被破坏了。
以前有人见过或知道什么会导致这种情况发生吗?
或者,对于任何进一步的诊断步骤的任何建议将被感激。
我知道这些查找器在较新的版本中已经被弃用,但是对于这个版本的软件来说,迁移到一个新版本并不是一个选项,我想深入了解一下,以防它指出一些更深层次的问题。
以下是软件版本/平台:
- Rails: 3.0.20
- Ruby: 1.9.2p180
- Postgres: 9.0.3
- SunOS <blanked-out> 5.10 Generic_137138-09 i86pc i386 i86pc
如果原因与自动加载有关,请添加更多信息:
SasUi::Event - class declaration: class SasUi::Event < SasUi
SasUi::Event - class location on disk: ../app/models/sas_ui/event.rb
There are two other events classes:
Data::Event - class declaration: class Data::Event < ActiveRecord::Base
Data::Event - class location on disk: ../app/models/data/event.rb
Event - class declaration: class Event < DelegateClass(SasUi::Event)
Event - class location on disk: ../app/models/event.rb
最佳答案
使用模块作为命名空间,而不是类。
您所做的(类下的类)称为内部类,不应超出上层类。
Nested classes question.