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