Why do models behave this way?

From the wiki…

Because Engines takes care of some of the load path, Ruby itself will
search for these files in order, and load the very first one it finds.
The paths this search will check are, in order:

* your app/models directory
* your lib directory
* the app/models directories in each engine, in active order
* the lib directories (and subdirectories) of each engine, in active 

order.

Why is it that models act like this? I would expect that you could place
a model in your app/models directory and override/add methods (just like
controllers).

Technical limitations? Design flaw?

Curious…thanks.

Apparently this bit of documentation hasn’t survived the transition to
the new wiki:

The ‘code merging’ that the Engines plugin does works for helpers and
controllers because of the naming convention the files containing
those classes have (whatever_controller… whatever_helper.rb and so
on). The Engines plugin overrides the loading mechanism so that when
one of those files is loaded, it merges the code with any similarly
named controllers in well-known places within your engines directory.

There is no such naming convention for models (or any other ruby
files), so there’s no way to determine where any other corresponding
files might be. If you asked ruby/rails to “require ‘guid’”, there’s
no way to determine just from the filename (and that’s all we have)
whether or not it’s a model from /app/models, a lib from /lib, or from
somewhere in /vendor (or anywhere else on the loadpath). Shy of going
through the WHOLE load path searching for similarly-named files and
loading them, there’s nothing we can do - and doing that would be a
spectacularly bad idea:

  • it would be very slow
  • it would risk loading unnecessary files along with all their
    dependencies - imagine looking for your ‘widget’ class and having a
    whole bunch of GUI code loaded into memory just because it contains a
    class of the same name.

So - technical limitations. Or ‘design flaw of Rails’ if you feel they
should’ve named the model files whatever_model.rb.

The solution I’d suggest, and that I’ve tried to present in the login
and user engines, is not actually putting any code into model classes
directly. Instead, create modules which can then be included into
model classes. To override the User class in the login engine, you
only have to create a user.rb in your /app/models directory, and
ensure that it has the line “include
‘LoginEngine::AuthenticatedUser’”. To override any methods defined in
the module, just redefine them in your class.

Hope this makes it a bit clearer.

  • james

James A. wrote:

The solution I’d suggest, and that I’ve tried to present in the login
and user engines, is not actually putting any code into model classes
directly. Instead, create modules which can then be included into
model classes. To override the User class in the login engine, you
only have to create a user.rb in your /app/models directory, and
ensure that it has the line “include
‘LoginEngine::AuthenticatedUser’”. To override any methods defined in
the module, just redefine them in your class.

Hope this makes it a bit clearer.

A lot - thanks. Hopefully this info makes it back to the wiki as well…

Feel free to post it up :slight_smile:

  • james

James A. wrote:

Feel free to post it up :slight_smile:

  • james

It’s there…modified the developer page a little as well.