Rails2.0 not reloading engine controllers/models

Hello,

Rails 2.0.1 does not reload engine-based plugin controllers and models
in development mode.

You have to restart mongrel to get them reloaded.

Anyone else has this issue?

Hi,

it works for me.

But generally, classes that are loaded through dependency autoloading
during the plugin load process (i.e. init.rb evaluation) won’t be
reloaded for subsequent requests in dev mode.

http://weblog.techno-weenie.net/2007/1/26/understanding-the-rails-plugin-initialization-process

(IMO this is a really annoying feature and it’s a pitty that it hasn’t
been revisited in Rails 2.0)

If this is related to your problem you can try to remove the affected
directories from Dependencies.load_once_paths like:

Dependencies.load_once_paths.delete(path)

Or try not to load them during the plugin loading stage …

Am 12.12.2007 um 17:41 schrieb Artūras Šlajus:

Engine-Developers mailing list
[email protected]
http://lists.rails-engines.org/listinfo.cgi/engine-developers-rails-engines.org


sven fuchs [email protected]
artweb design http://www.artweb-design.de
grünberger 65 + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin + 49 (0) 171 - 35 20 38 4 (mobile)

I’m not sure that Rails has ever allowed automatic reloading of code
from plugins in development - can anyone confirm this?

Sven F. wrote:

Hi,

it works for me.

But generally, classes that are loaded through dependency autoloading
during the plugin load process (i.e. init.rb evaluation) won’t be
reloaded for subsequent requests in dev mode.

i wasn’t talking about those, i was talking about
vendor/plugins/your_plugin/app/models/foo.rb (same with controllers)

It used to work perfectly with 1.2, now it just loads them once :frowning:

Am 12.12.2007 um 17:55 schrieb Sven F.:

it works for me.

Whoops, sorry.

It works for me in an outdated version that I’m still using for a
client … but it doesn’t seem to work with the current trunk (which
is, IMO, correct).

Am 12.12.2007 um 18:51 schrieb James A.:

I’m not sure that Rails has ever allowed automatic reloading of code
from plugins in development - can anyone confirm this?

Yes, I think this is true.

They once tried to change it, but ran into issues with plugins that
rely on their classes not being auto-reloaded and thus invented
Dependencies.load_once_paths. See Rick’s post on this:
http://weblog.techno-weenie.net/2007/1/26/understanding-the-rails-plugin-initialization-process

I strongly believe that this is the wrong approach to it though, as it
leads to all kinds of weird side-effects. A better approach to it
would be to whitelist those plugins that don’t want to be auto-
reloaded but auto-reload everything else. (Actually there’s even a
config.load_once_paths feature that would allow to do this.)


sven fuchs [email protected]
artweb design http://www.artweb-design.de
grünberger 65 + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin + 49 (0) 171 - 35 20 38 4 (mobile)

Sven F. wrote:

somewhere

Rails::Plugin.class_eval do
def reloadable!
load_paths.each { |p| Dependencies.load_once_paths.delete§ }
end
end

in your plugin init.rb

reloadable!

evil, evil hack :expressionless:

thanks thou…

they could make vendor/plugins/load_once/ and vendor/plugins/reloadable

perhaps i’ll make a patch and fix it! =) it would be cool :slight_smile:

what do you think of this idea?

Am 12.12.2007 um 22:17 schrieb Artūras Šlajus:

reloadable!
evil, evil hack :expressionless:

Well it’s the technique that Rick O. suggested, who also seems to
be the one who implemented that whole load_once_paths thing (not
totally sure though).

So I think this is the “official” way of forcing the framework to
reload your plugin classes.

thanks thou…

they could make vendor/plugins/load_once/ and vendor/plugins/
reloadable

perhaps i’ll make a patch and fix it! =) it would be cool :slight_smile:

Where would you patch that?

Actually I don’t know enough about the context and history of that
feature to judge that. But I’ll try and keep nagging on Rick to
finally fix that thing in Rails core. I think everything that raises
awareness about this might be a potential move forward.


sven fuchs [email protected]
artweb design http://www.artweb-design.de
grünberger 65 + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin + 49 (0) 171 - 35 20 38 4 (mobile)

Am 12.12.2007 um 21:23 schrieb Artūras Šlajus:

i wasn’t talking about those, i was talking about
vendor/plugins/your_plugin/app/models/foo.rb (same with controllers)

Yes, like I said in the other mail I mistakenly looked at an outdated
version. You’re right that this isn’t going to work by default.

It used to work perfectly with 1.2, now it just loads them once :frowning:

That might have to do with the fact that Engines now uses the new
plugin architecture that’s implemented in Rails 2.0 rather than
shipping it’s own stuff.

Rails makes it so that your plugin load paths are added to
Dependencies.load_once_paths which means that those classes aren’t
reloaded.

You can remove them from there, though:

somewhere

Rails::Plugin.class_eval do
def reloadable!
load_paths.each { |p| Dependencies.load_once_paths.delete(p) }
end
end

in your plugin init.rb

reloadable!


sven fuchs [email protected]
artweb design http://www.artweb-design.de
grünberger 65 + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin + 49 (0) 171 - 35 20 38 4 (mobile)

Sven F. wrote:

Actually I don’t know enough about the context and history of that
feature to judge that. But I’ll try and keep nagging on Rick to
finally fix that thing in Rails core. I think everything that raises
awareness about this might be a potential move forward.

Here goes simple but usefull solution!

— rails-2.0.1/lib/rails/plugin/loader.orig.rb 2007-12-13
00:01:38.000000000 +0200
+++ rails-2.0.1/lib/rails/plugin/loader.rb 2007-12-13
00:11:19.000000000 +0200
@@ -42,11 +42,14 @@
#
# Plugin load paths are also added to Dependencies.load_paths,
and Dependencies.load_once_paths.
def add_plugin_load_paths

  •    reloadable_path = File.join('vendor', 'plugins', 'reloadable')
        plugins.each do |plugin|
          plugin.load_paths.each do |path|
            $LOAD_PATH.insert(application_lib_index + 1, path)
            Dependencies.load_paths      << path
    
  •        Dependencies.load_once_paths << path
    
  •        if path.index(reloadable_path).nil?
    
  •          Dependencies.load_once_paths << path
    
  •        end
          end
        end
        $LOAD_PATH.uniq!
    

@@ -147,4 +150,4 @@

  end
end

-end
\ No newline at end of file
+end

And here it’s in all its glory :slight_smile:

pp Dependencies.load_paths - Dependencies.load_once_paths
["/home/x11/www/rails/vk-diplominis/test/mocks/development",
“/home/x11/www/rails/vk-diplominis/app/controllers/”,
“/home/x11/www/rails/vk-diplominis/app”,
“/home/x11/www/rails/vk-diplominis/app/models”,
“/home/x11/www/rails/vk-diplominis/app/controllers”,
“/home/x11/www/rails/vk-diplominis/app/helpers”,
“/home/x11/www/rails/vk-diplominis/components”,
“/home/x11/www/rails/vk-diplominis/config”,
“/home/x11/www/rails/vk-diplominis/lib”,
“/home/x11/www/rails/vk-diplominis/vendor”,
“/var/lib/gems/1.8/gems/rails-2.0.1/lib/…/builtin/rails_info/”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_login_engine/app/controllers”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_login_engine/app/helpers”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_login_engine/app/models”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_login_engine/lib”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/datepicker/lib”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/flash_divs/lib”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/gallery_engine/app/controllers”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/gallery_engine/app/helpers”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/gallery_engine/app/models”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/gallery_engine/lib”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/groups_engine/app/controllers”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/groups_engine/app/helpers”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/groups_engine/app/models”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/groups_engine/lib”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/hex_encoder/lib”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_communication_engine/app/controllers”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_communication_engine/app/helpers”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_communication_engine/app/models”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_communication_engine/lib”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_profiles_engine/app/controllers”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_profiles_engine/app/helpers”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_profiles_engine/app/models”,
“/home/x11/www/rails/vk-diplominis/vendor/plugins/reloadable/user_profiles_engine/lib”]

Isn’t that just cool? :slight_smile:

err, a tiny weak to use String#include? not #index

— rails-2.0.1/lib/rails/plugin/loader.orig.rb 2007-12-13
00:01:38.000000000 +0200
+++ rails-2.0.1/lib/rails/plugin/loader.rb 2007-12-13
00:15:49.000000000 +0200
@@ -42,11 +42,14 @@
#
# Plugin load paths are also added to Dependencies.load_paths,
and Dependencies.load_once_paths.
def add_plugin_load_paths

  •    reloadable_path = File.join('vendor', 'plugins', 'reloadable')
        plugins.each do |plugin|
          plugin.load_paths.each do |path|
            $LOAD_PATH.insert(application_lib_index + 1, path)
            Dependencies.load_paths      << path
    
  •        Dependencies.load_once_paths << path
    
  •        unless path.include? reloadable_path
    
  •          Dependencies.load_once_paths << path
    
  •        end
          end
        end
        $LOAD_PATH.uniq!
    

@@ -147,4 +150,4 @@

  end
end

-end
\ No newline at end of file
+end

Artūras Šlajus wrote:

Sven F. wrote:

Where would you patch that?

http://dev.rubyonrails.org/ticket/10488

no comments? :frowning:

Hi Artūras!

Sorry I have missed that one.

Am 14.12.2007 um 09:37 schrieb Artūras Šlajus:

Artūras Šlajus wrote:

Sven F. wrote:

Where would you patch that?

http://dev.rubyonrails.org/ticket/10488

Hey, that really was a quick shot :slight_smile:

Personally I tend to discus stuff like this first and then propose a
patch. But I already learned that this isn’t always the way to go :wink:

I think it’s a good idea!

But it has the drawback that it nails things to a very specific
concern. Maybe folks want to organize their plugins in a different
way? I’m working for a client who most probably would not want to use
this directory layout because he already structures things by other
criteria.

That said, I think it’s really useful to generate some fuss around
this topic. It might take ages to even get heard by some rails-core
member as they don’t seem to use plugins that much anyways.


sven fuchs [email protected]
artweb design http://www.artweb-design.de
grünberger 65 + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin + 49 (0) 171 - 35 20 38 4 (mobile)

Sven F. wrote:

Where would you patch that?

http://dev.rubyonrails.org/ticket/10488

Hmmm. Something’s occurred to me.

With the implementation of engines 1.1.x, the app/models directory
wasn’t involved dur the plugin loading process, which meant that it
wouldn’t be added to load_once_paths.

However, with 2.x, we’re now hooking into a plugin-generic load_paths
mechanism, which means that paths we add to the $LOAD_PATH via this
are candidates for inclusion in load_once_paths.

This could explain why reloading classes from plugins (well, from
app/models) used to be easier, but now requires some extra steps.

Does this make sense? I’m not sure that there’s an ideal solution,
unfortunately - Rails probably wants to keep the notion of
“load_once_paths”, and reverting the behaviour of the engines plugin
makes it significantly more complicated.

I’m curious about which plugins might break without load_once_paths…

On Wed, Dec 12, 2007 at 05:51:48PM +0000, James A. wrote:

I’m not sure that Rails has ever allowed automatic reloading of code
from plugins in development - can anyone confirm this?

No idea about Rails, but with Engines in 1.x it used to Just Work.

What’s even worse is that if you include engines and load a model from
an engine in your app’s model, it gets marked unreloadable, too!
So if you have

app/models/user.rb

require_dependency(File.join(RAILS_ROOT,
“vendor/plugins/accounts/app/models/user.rb”))

class User < ActiveRecord::Base

end

and you change something in there, you will need to restart your server,
too!
This really makes it unusable, IMHO.

Right now I’m just hacking around it by putting
Dependencies.load_once_paths = []
in my environment.rb. It’s a hack, but without it really really sucks.

Cheers,
Peter B.
Solide ICT - http://www.solide-ict.nl

Am 25.01.2008 um 12:26 schrieb James A.:

This could explain why reloading classes from plugins (well, from
app/models) used to be easier, but now requires some extra steps.

Does this make sense?

Absolutely. I’m pretty sure this is the reason for this kind of
behaviour.

I’m not sure that there’s an ideal solution,
unfortunately - Rails probably wants to keep the notion of
“load_once_paths”, and reverting the behaviour of the engines plugin
makes it significantly more complicated.

IMO there’s no sane reason as to why plugins and libs should behave
differently from any app model class by default. It’s not only
counterintuitive but leads to major issues when one tries to work
around it.

I’ve talked to Rick O. briefly about this issue on IRC and he
agreed that this behaviour not only sucks but also might be something
that should be changed in some future major Rails release (like Rails
3.0).

I’m curious about which plugins might break without load_once_paths…

Me too.

Reportedly there are quite some plugins that rely on the behaviour of
plugins not being reloaded. Thus it would be kind of an “political”
issue to change this and break “lots of plugins”.

Maybe you’re somebody who could raise this question on Rails core?

from
end
Cheers,

  • J *
    ~

Engine-Developers mailing list
[email protected]
http://lists.rails-engines.org/listinfo.cgi/engine-developers-rails-engines.org


sven fuchs [email protected]
artweb design http://www.artweb-design.de
grünberger 65 + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin + 49 (0) 171 - 35 20 38 4 (mobile)

On Fri, Jan 25, 2008 at 11:26:15AM +0000, James A. wrote:

This could explain why reloading classes from plugins (well, from
app/models) used to be easier, but now requires some extra steps.

Does this make sense?

Sounds logical.

I’m not sure that there’s an ideal solution,
unfortunately - Rails probably wants to keep the notion of
“load_once_paths”, and reverting the behaviour of the engines plugin
makes it significantly more complicated.

Maybe we can somehow hack Rails::Plugin::Loader#add_plugin_load_paths
to exclude any paths added by engines, then we’re good. I don’t know
if Engines can currently distinguish between an Engine and a regular
plugin, though.

I’m curious about which plugins might break without load_once_paths…

I think a lot will fail. Simply commenting out the line in the above
mentioned module gave me a stack overflow somewhere in
pluginify_sources.
However, after retrying another time I didn’t get this error.
Maybe the plugin_load_once_paths is an attempt to cover up some bug
in Rails’ autoloading system?

Cheers,
Peter B.
Solide ICT - http://www.solide-ict.nl