Best practice organization of rails directories

I have a few "outlier" cases of ruby files used by my rails app and am
trying to decide where to put them.

1. Models that are not ActiveRecord models. Suggestion: app/models

2. Utility classes which are invoked by the application during normal
operation. Not sure between app/utility - on the theory that they are
part of the application, or lib/utility - on the theory that they are
not rails classes at all.

Other then aesthetics, there might be issues regarding rails finding and
loading the classes, or perhaps relating to development vs. production
mode, or other trade offs that I don't see. I suspect these are topics
of debate and taste, so I am looking more for some kind of authoritative
link or source.

Thanks for your pointers!

- Pito

Pito Salas wrote in post #955126:

I have a few "outlier" cases of ruby files used by my rails app and am
trying to decide where to put them.

1. Models that are not ActiveRecord models. Suggestion: app/models

There is a pernicious assumption among many Rails developers that models
have to be ActiveRecord subclasses, and that there's something abnormal
if they're not. Nothing could be further from the truth.

The term "Model", in MVC nomenclature, refers to a class that represents
an actual domain object. Where a model class stores its data (in the DB
or otherwise), and whether it uses ActiveRecord to do so, are
implementation details that have no bearing on whether the class is in
fact a model or whether it belongs in app/models.

Anything model-like, whether or not it talks to the DB, goes in
app/models.

2. Utility classes which are invoked by the application during normal
operation. Not sure between app/utility - on the theory that they are
part of the application, or lib/utility - on the theory that they are
not rails classes at all.

lib doesn't imply that something is "not a Rails class".

Utility classes (that are not models) go in lib. I don't see what the
utility directory inside there gains you; lib is already utilities.

Other then aesthetics, there might be issues regarding rails finding and
loading the classes, or perhaps relating to development vs. production
mode, or other trade offs that I don't see. I suspect these are topics
of debate and taste, so I am looking more for some kind of authoritative
link or source.

The above recommendations are more or less the standard Rails way. If
you introduce additional directory nesting, then you need to namespace
your classes correspondingly if you want Rails to autoload them.

Thanks for your pointers!

- Pito

Best,

Marnen Laibow-Koser wrote in post #955146:

Utility classes (that are not models) go in lib. I don't see what the
utility directory inside there gains you; lib is already utilities.

To me lib/ implies a library used by the application. not part of the
application itself, which is why I considered added another top level
subdirectory under app/ That way app/ is the complete contents of the
application.

Does that make sense or do you see a problem with that? Also does it
help with auto loading of classes?

-- Pito

Marnen Laibow-Koser wrote in post #955146:

Utility classes (that are not models) go in lib. I don't see what the
utility directory inside there gains you; lib is already utilities.

To me lib/ implies a library used by the application. not part of the
application itself, which is why I considered added another top level
subdirectory under app/ That way app/ is the complete contents of the
application.

A minor aside: app still won't include the complete contents, because
of config, db, public, &c.

Does that make sense or do you see a problem with that? Also does it
help with auto loading of classes?

In the sense that, by default, app is included in the autoload path,
but lib is not, for reasons that escape me.

Your view of lib is reasonable, but it is not particularly railsy:
libraries are typically loaded either via the vendor directory, or
simply as gems listed in Gemfile. 'lib' doesn't really have the same
meaning that it typically does, in say a J2EE app where it usually is
a dumping ground for third party jars.

That said, there is nothing particularly bad about adding
subdirectories in app. Just remember that if you want autoloading to
work, you have to make sure that the names match the directories, and
if you have directories that aren't included in the fully qualified
name of a class, to add those directories to the autoload path.

e.g.
app/widgets/foo.rb could have class Widgets::Foo, or it could have
class Foo if you added app/widgets to the autoload path, which IIRC,
is accomplished in config/application.rb.

    config.autoload_paths += %W( #{config.root}/app/widgets )

and, again IIRC, just basically updates
ActiveSupport::Dependencies.autoload_paths