相当复杂,所以我会尽量简单。
我有一个 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 上添加了最后一行来加载所有其他实体。(也尝试使用初始化程序,但它没有帮助,因为当代码更改时它没有重新加载)。
我的问题如下:
- 我启动服务器。通过查看一些调试打印,我可以看到所有其他类都已加载,并且当我查看 @@str_to_ent 映射时 - 它已初始化。
- 我打电话给控制器。一切都好。我一直用各种论据来称呼它——一切都很好。
- 我更改了任何文件(添加空格线)
- 从现在开始,我将收到一条错误消息,指出没有实体与给定类型关联(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 重新加载类时我也需要这些方法的操作。(我对重新评估类没有问题,我的问题是它重新评估了基础并跳过了子类)。
谢谢,
扎克