Quite complex, so I'll try to do it as simple as I can.
I have a rails application, and have a problem when I work in developement mode and change my code when the server is running.
I have the following models (with only the relevant code, if you think you need more - tell me and I'll add):
---- 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
I want entities to be assigned with a type (string) for further lookups (in one of the controllers I need the map between the textual representation of an entity and the entity class itself).
Obviously I need all sub classes entities to be loaded, that's why I added the last line on entity.rb that loads all others. (also tried using an initializer, but it didn't help as it's not reloaded when the code changes).
My problem goes as follows:
I do understand that when the code changes, rails (in development mode) re-evaluates the classes files. I could also see that in my debug prints. It's requiring the entity.rb class and therefore overrides @@str_to_ent with {}, but then although it requires 'ip_entity.rb', and 'phone_entity.rb', it seems that it doesn't actually evaluates them since Entity.with_type isn't called again and the @@str_to_ent hash is still empty. That's what causing the problem.
The only way I can overcome this, is to restart the server, but that makes the whole debugging process very annoying...
Can anyone help with a solution? What's the best-practice when I need to "configure" my classes somehow (pretty similar to "attr_accessible", or "validates_presence_of") but I need the actions of these methods to stay with me even when rails reload the class. (I don't have a problem with re-evaluating the classes, my problem is that it re-evaluates the base and skips the sub-classes).
Thanks,
Zach
If I correctly understand what you are trying to achieve is called Single Table Inheritance. It is Rails default behavior when implementing inheritance on models.
Search this documentation for Single Table Inheritance.
UPDATE
I think using require_dependency
should allow you to reload subclasses as well :
class Entity
...
end
require_dependency 'ip_entity'
require_dependency 'phone_entity'