Controllers
Last update: 2024-11-29
Status: draft
The controller is smart enough to know who to ask for information (to the models) and who to pass it to display it correctly (to the views), without doing the heavy lifting in any case.
After an HTTP request is received, it goes through the router, who sends it to the appropriate controller and action. Then, all the variables created in that instance are passed to the view and sent back to the browser.
A simple example of an index action of a controller:
class PostsController < ApplicationController
def index
@posts = Post.all
end
end
This will get the @posts instance variable and pass it to the view app/views/posts/index.html.erb.
Naming matters
The instance variables from the controller action are passed to a view with the same name as the action, in a folder with the same name as the controller, in the app/views folder.
Rendering other pages
For example, when you create a new post, the form is displayed in the controller action posts#new. When submitted, it goes to posts#create, where it’s validated and saved. Then it redirects you to the newly created post.
But if it fails, you want to go back to the posts#new with the temporary information so you can fix it and not start from scratch.
This is how you do both cases:
class PostController < ApplicationController
def new
# We create (even tho we don't save it) a @post instance variable because
# we want the view to know which fields needs to display
@post = Post.new
end
def create
if @post.save
# It worked, so we show the new post
redirect_to post_path(@post.id)
# A shorter way to achieve the same
redirect_to @post
else
# Something went wrong, so we go back to new with the error message
render :new, status: :unprocessable_entity
end
end
Multiple render and redirects
Keep in mind that neither render nor redirect_to stops the controller action like a return would do. Be careful with that.