On 2/27/07, Brett W. [email protected] wrote:
Really? You can’t mix a module from a plugin into your app - you
have to add it into Rails?? That just seems somehow wrong to me. I
thought I could mix a module in anywhere I want - if the main class
gets reloaded, why won’t it’s dependencies get reloaded as well? Is
that in general, or only with engine plugins?
You’re talking about a few things here. Imaging the situation:
app/models/a.rb:
class A
end
app/models/b.rb
class B
include C
end
vendor/plugins/monkey/lib/c.rb
module C
end
vendor/plugins/monkey/init.rb:
A.send(:include, C)
When your application first loads, init.rb is evaluated, and C is
included into A. C is also included into B, as per normal. At the end
of the request, A and B are dutifully unloaded to make way for any
changed versions. The next request causes Rails to try to find A
again, which it does in app/models/a.rb, and so it loads that file.
However, because vendor/plugins/monkey/init.rb is only ever evaluated
at the start of the request cycle, the “new” A will NOT include the
module C.
Since B explicitly refers to C, when Rails tries to reload B from
app/models/b.rb, it re-reads the class definition and includes C as
you’d expect.
The point here is that the only place where it states that A should
include C is a file that is only ever evaluated once, and that
information is lost when the target class is unloaded. This is what
plugin developers typically send includes to ActionController::Base,
not ApplicationController.
In any case, I’m running into the same problem with ActiveRbac.
First run, everything works. Second run, methods for a model just
disappear. In order to create a model that doesn’t have to be
completely copied into the application to be overridden, they created
a model file that simply includes a mixin module with all the real
code. So to override the model in my app I create the model file,
include the mixin files, and my new functions.
That’s basically what’s going on with class B, above.
The problem seems to be in one of the models that I don’t override.
First run everything is fine, second run non of it’s methods are
found. It’s not just the mixed in ones.
Just to be sure that I know what you’re referring to:
- there is a model within a plugin
- it has, say, method “do_something” defined directly in the class
- on the second request, the model class is still available but the
method has disappeared
Is that right?
I added a method straight
in to the model - it wasn’t available on the second run. Here is an
interesting error I get if I try to do a find on the model:
ArgumentError: A copy of ActiveRbacMixins::UserMixins::Core has been
removed from the module tree but is still active!
I can’t speak for ActiveRbac specifically, but I’ve never, ever
encountered this error. Very weird.
This worked fine in the previous Rails and Engines. So this is new
behavior. What’s the best way to fix it?
Since any version of ActiveRbac that was compatible with the engines
plugin 1.1.x releases isn’t compatible with the 1.2 release, you
should also note that ActiveRbac must’ve changed.
If you can reproduce this in a clean project using the engines plugin
and a toy plugin to contain the model, please zip it up and email it
directly to me. I’m very keen to resolve this, but I need to be able
to reproduce the behaviour…
Cheers