Hi, I'm getting a little confused how Rails handles loading models.
I'm on development mode, using Rails 3.1.0.rc1 on ruby 1.8.7
My application models are:
Curso
Legislacao
Usuario
And I have another model that is loaded from a gem Im trying to build:
Cidade
My gem is actually a simple engine:
require 'active_record'
require 'my_gem/app/models/cidade'
module MyGem
class MyGemEngine < Rails::Engine
config.to_prepare do
puts ActiveRecord::Base.descendants
end
end
When I start the server it prints, as expected:
=> Booting Mongrel
=> Rails 3.1.0.rc1 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
Cidade
=> Debugger enabled
But when I try to login and get redirected to the root page
(Curso#new) it prints:
Cidade
Curso
Legislacao
Started GET "/" for 127.0.0.1 at Sun May 29 19:38:58 -0300 2011
Processing by CursosController#new as HTML
Usuario Load (0.3ms) SELECT `usuarios`.* FROM `usuarios` WHERE
`usuarios`.`id` = 1 LIMIT 1
As you can see, the Usuario class was loaded, but was not added to
ActiveRecord::Base.descendants. Which makes me think that it was
loaded after the to_prepare block.
Shouldnt the to_prepare block be called after all loadings had already
happened?
I cant figure out how to eager load this. I could make it load all
models all the time, but is a great overhead, since Ill be dealing
with lots of models in the future.
I cant figure out how to eager load this. I could make it load all
models all the time, but is a great overhead, since Ill be dealing
with lots of models in the future.
Can anyone help me with that ??
Models in development mode are lazily loaded and then unloaded after a
request is processed, if you wanted to eagerly load a particular model
just reference it in the to_prepare block. However, that will
probably lead to strange behaviour where your classes no longer get
reloaded.
The short version is, in development mode don't try to do anything
which relies on classes hanging around, because they don't.
The short version is, in development mode don't try to do anything
which relies on classes hanging around, because they don't.
One of the things I need to do is dynamically defining table_prefix,
based class location. Models loaded from inside the gem will have a
specific prefix and the ones outside them gem will have another.
Something this would work, loading and unloading on every request.
Dir[File.join("#{Rails.root}/app/models", '*.rb')].each { |f| require
f }
But it would add a huge overhead to the load time on development.
Is there a model load hook or something like that ?
Is there a model load hook or something like that ?
There's not at present no, however for your case you could simply
override the definition of the method table_name_prefix to do what you
require for your particular subclasses.
I agree that table_name_prefix is probably your best bet but if you
find yourself needing something more dynamic look at the
set_table_name method. It (optionally) accepts a block whose return
value is used to set the table name. Use this to compute a model's
table name on-the-fly with minimal hassle. Also consider that nested
AR models automatically prepend their parent's table name to their
table name which sounds to me a lot like what you are trying to do.
Maybe that's an option for your situation. Best of luck to you.