我有一个问题,在我的 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)
SasUi::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% 的情况下都有效,我们有几百个客户在使用这个软件,但非常偶尔,一个客户会看到这个问题。注销应用程序并重新登录似乎可以解决问题。
应用程序中有多个线程访问这些模型,这是另一种可能的探索途径。
据我了解,动态查找器通过覆盖缺少方法的方法,并在 _ 字符上拆分被调用方法的名称以提取请求的属性名称来工作。如果提取的属性存在于模型的attribute_names中,则进行查询,否则将抛出原始的NoMethodError。
attribute_names 具有以下文档:
如果它不是抽象类并且表存在,则将列名数组作为字符串返回。否则返回一个空数组。
除了上面列出的例外,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