Controllers
Roles of a controller
A Controller can end up with a lot of responsibilities. The first goal of a controller is to render a view to a client based on a request. A lot of logic can happen in the process but think to controller like a "glue" to make the application core logic accessible from the outside.
Location
app/controllers/
- Should be suffix with
_controller.rb
Dos
- Use
before_action
withonly
andexcept
if necessary - Use
strong_params
for model mutations (POST, UPDATE) - Use private methods if needed but the goal is to limit the logic in controllers. private method should only be used to render errors or generic redirects
- Use Domain
- Use Services
- Use Presenters
- Use Decorators
- Validate the
params
- Try to keep the standard action names for CRUD: (
index,show,edit,new,update,create,delete
) - Do authentication
- Do authorizations (ACL)
- Manipulate the
sessions
for each visitor - Manipulate the
flash
notices - Do
redirect
- Do
render
- Can call Mailers
- Can call Background Jobs
- Try to keep coherent param names in different views, to limit the params-handling code
Don'ts
- Do complexe ActiveRecord queries (use Query Objects instead)
- Create complexe if/else workflow in one action (use Services instead)
- Have too much private methods (use Domain business logic or other classes instead)
- Call external API services (HTTP requests or what ever)
- Fetch data from multiple models: Try to limit the number and kind of models you call in an action. Create another class if you need to manipulate multiple models
- Know too much about your app, the database and caching stuff: The configuration for databases, caching and others things are done in
config/
.
Code
class ExampleController < ApplicationController
before_action :authenticate_user
def dashboard
@data = UserDashboard.new(params).call
end
def register
new_user = UserRegistration.new(params).call
redirect_to dashboard_path
end
def create
event = Event.new(event_params)
if event.save
redirect_to event_path(event)
else
render "new"
end
end
private
def event_params
params.require(:event).permit(:name, :start_at, :end_at)
end
end