3

我有一个问题,在我的 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
4

1 回答 1

0

使用模块作为命名空间,而不是类。

您所做的(类下的类)称为内部类,不应在上层类之外达到。

嵌套类问题。

于 2013-12-27T14:47:40.813 回答