When I first started with Rails, my routes, models, and tables always matched up.
I had resources :posts
, a Post
model, and a posts
table. It felt tidy and predictable.
But here’s the thing: you don’t have to keep it that way—and you probably shouldn’t.
Let’s say you have an Event
resource. Events can have nested child events. When a user deletes a parent event, they should be able to choose:
Now, you could overload EventsController#destroy
with extra parameters to handle this logic. But why not give this behavior its own home?
resources :events do
resource :deletion, only: [:new, :create], module: :events
end
This sets up a controller like Events::DeletionsController
, which handles just the deletion UI and logic. You can present a simple form with options, event embedding it in a modal with a Turbo Stream, and link to it cleanly:
<%= link_to "Delete", new_event_deletion_path(@event), class: "btn-danger" %>
EventsController
focused on the core resource lifecycle.POST /events/:id/deletion
is clear and purposeful.Look at your app. Where are you jamming complex logic into overly generic controllers? What behaviours deserve a name, a route, a view—even without a dedicated model or table?
You’re allowed to make up resources. Rails won’t stop you.