rails new comes a lot of decisions. Rails has great conventions but lacks documentation and in-house libraries for services, presenters, form objects. There’s also the debate about what to do with
lib. Like most people, I have my preferred ways of doing things that serve me (and my clients) well. Admittedly, a lot of the inspiration for my ways of doing things comes from GitLab. Hats off to them for having a seemingly extensible and maintainable codebase.
exploring THE APP DIRECTORY
Inside each of my project’s app directory, I create a few new directories:
For each resource that a controller interacts with, I have a directory inside the
services directory for it. Inside that resource-specific directory I have corresponding POROs for controller actions. An example would be
services/users/follow_service.rb if a route was
presenters are most likened to that of a decorator pattern. In fact I should probably be using something like draper or cells but I’m comfortable with my POROs until I have a use case that can take advantage of the additional functionality that one of those libraries provide.
finders directory is, admittedly, sparsely populated but important nonetheless. It contains POROs that find a resource (or collection of resources) based on specific params.
forms directory contains form objects that act like
ActiveModel and respond to the conventions that SimpleForm expects.
the lib directory
There’s some debate about what actually goes in lib, and while I’ve contributed to Rails but I wouldn’t call myself a Rails contributor.
Because we have an
app directory, I would say it’s incorrect to app-specific code inside
lib. But at the same time, I think it’s incorrect to throw just anything inside
Some loose rules (there are many exceptions to these rules) that I think I follow:
- if it doesn’t have routes (such as ActiveAdmin code, or an API with Grape),
- if it doesn’t behave like
- if it doesn’t initialize with or otherwise call objects that behave like
- if it doesn’t initialize with or otherwise call
you can argue it belongs in
Note: GitLab, my favorite codebase, has their grape setup within
lib. … I know, I know. My rules aren’t perfect.
Inside Kioskable, my current project, I have a whopping 16 directories inside
app. That’s 9 more than the default 7.
workers. Some of these are specific to a gem:
admin for ActiveAdmin,
api for Grape,
policies for Pundit,
workers for Sidekiq.