0

相当复杂,所以我会尽量简单。

我有一个 Rails 应用程序,当我在开发模式下工作并在服务器运行时更​​改我的代码时遇到问题。
我有以下模型(只有相关代码,如果您认为需要更多 - 告诉我,我会添加):

---- file : app/models/entity.rb ----
class Entity < ActiveRecord::Base

  @@str_to_ent = {}

  def self.with_type(given_type)
    given_type = given_type.to_sym
    if @@str_to_ent[given_type] and self!=@@str_to_ent[given_type]
      raise "Type #{given_type} was already associated by #{@@str_to_ent[given_type}"
    end
    @@str_to_ent[given_type] = self
  end

  def self.by_type(type)
    @@str_to_ent[type.to_sym]
  end

  # rest of code
end
Dir["#{File.dirname(__FILE__)}/*.rb"].each {|file| puts "requiring #{file}"; require file }


---- file : app/models/ip_entity.rb ----
class IpEntity < Entity
  with_type :ip

  # rest of code
end

---- file : app/models/phone_entity.rb ----
class PhoneEntity < Entity
  with_type :phone

  # rest of code
end

我希望为实体分配一个类型(字符串)以进行进一步查找(在其中一个控制器中,我需要实体的文本表示与实体类本身之间的映射)。
显然我需要加载所有子类实体,这就是为什么我在 entity.rb 上添加了最后一行来加载所有其他实体。(也尝试使用初始化程序,但它没有帮助,因为当代码更改时它没有重新加载)。

我的问题如下:

  1. 我启动服务器。通过查看一些调试打印,我可以看到所有其他类都已加载,并且当我查看 @@str_to_ent 映射时 - 它已初始化。
  2. 我打电话给控制器。一切都好。我一直用各种论据来称呼它——一切都很好。
  3. 我更改了任何文件(添加空格线)
  4. 从现在开始,我将收到一条错误消息,指出没有实体与给定类型关联(Entity.by_type 在先前初始化的类型上返回 nil)。

我确实明白,当代码更改时,rails(在开发模式下)会重新评估类文件。我也可以在我的调试打印中看到这一点。它需要 entity.rb 类,因此用 {} 覆盖 @@str_to_ent,但是虽然它需要 'ip_entity.rb' 和 'phone_entity.rb',但它似乎实际上并没有评估它们,因为 Entity.with_type 是'没有再次调用,@@str_to_ent 哈希仍然是空的。这就是造成问题的原因。

我可以克服这个问题的唯一方法是重新启动服务器,但这会使整个调试过程非常烦人......

任何人都可以提供解决方案吗?当我需要以某种方式“配置”我的类(非常类似于“attr_accessible”或“validates_presence_of”)时,最佳实践是什么,但即使在 rails 重新加载类时我也需要这些方法的操作。(我对重新评估类没有问题,我的问题是它重新评估了基础并跳过了子类)。

谢谢,
扎克

4

1 回答 1

1

如果我正确理解您要实现的目标,则称为单表继承。在模型上实现继承时,这是 Rails 的默认行为。

在此文档中搜索Single Table Inheritance

更新

我认为 usingrequire_dependency也应该允许您重新加载子类:

class Entity
  ...
end
require_dependency 'ip_entity'
require_dependency 'phone_entity'
于 2012-12-23T15:45:16.840 回答