- Read Tutorial
- Watch Guide Video
In the last guide we walked through the basic set of files that were created by the scaffold generator. Then our main focus became the controller.
Traffic Cop
In many ways, the controller is functioning like the traffic cop of your entire application. The controller:
- Communicates with the routing system
- Assigns what values should be made available to the view
- Reaches out to the the database via model calls
It is essential to understand everything that the controller does for our application.
Method = Action
In the last guide, we went through the index
and show
methods. A common convention in Rails is to refer to the methods in the controller as actions. Please note that those they are synonymous and I will use method and action interchangeably throughout the course.
In this guide we will analyze the new, create, update, edit, and destroy actions.
New vs. Create
Let's start with new
action. As you may have guessed, new
makes it possible to compose a new blog. However, it’s the create
method that actually generates a new blog.
That may seem a bit confusing because new and create seem so similar. Once we explore the subtle differences you will understand how each of these actions work.
Start by closing your controller directory and moving down the file tree to the views directory.
Views contains two subdirectories called blogs
and layouts
. We want to focus on the blogs, so open that folder.
With the blogs
folder open, you'll see a list of items. Most of these items map to the actions/methods in controller. You will note that the following items map to our controller:
- index
- new
- show
- edit
.
(Developers note: Now is a good time to split your Sublime screen so you can see two files at once. Remember the way to do this is to click View < Layout < Rows: 2 . Conversely you could choose View < Layout < Columns: 2. Use whichever format works better for you! Now you should have your blogs_controller.rb file open in one pane and new.html.erb open in the other.)
Instantiation
To review, the new
method does not actually create a new blog. The only thing new
can do is give us the ability to do something called instantiation
. Instantiation give us the opportunity to establish a new instance of an item. In this case it gives us the ability to establish the instance of a new blog.
We can get a better understanding of this if you look at the new
method in your controller. This method can’t create a new blog because it does not take in any parameters. (Remember a blog needs a title and a body).
def new @blog = Blog.new end
If you go to our application in the browser "localhost:3000/blogs" and click on the new button you will see that you have a form with empty elements. That is really all that the new method does for us.
You can think of it like this: when you are on your blog index page and you click on the new blog link, that is the action that triggers the new
method. From there we have to connect with the create
method to complete the generation of the blog.
Clarification from the View File
If you look at the new.html.erb
file, which is mapped to the new action in the controller, you will see line 3 states: render ‘form’.
Succinctly, the new
method in the controller is telling the browser to display the new blog form. That is it.
When you enter the details (title and body) and click on the button called "Create blog", that is when a blog is created and the values you entered as parameters are stored in the database.
Create Method
If you look at the create
method in the blogs controller, you will see it contains a lot of logic.
def create @blog = Blog.new(blog_params) respond_to do |format| if @blog.save format.html { redirect_to @blog, notice: 'Blog was successfully created.' } format.json { render :show, status: :created, location: @blog } else format.html { render :new } format.json { render json: @blog.errors, status: :unprocessable_entry } end end end
First, Take note of line 31. This has the similar .new
syntax, but it is followed by (blog_params). This line of code tells us that the method takes the parameters of title and body that you type into the form and uses that data to create an instance in the database.
Workflow
Notice how intuitive Rails was in building out this application for us: it gave this button on the blog form with the title “Create Blog”.
You can change the this button text to 'publish', or 'save', or whatever serves your purpose (we will do this a different guide), but this “Create Blog” default is a subtle way Rails is pointing out the workflow of the app. It is saying if you click this it will trigger the create action in your controller.
Validation Logic
Let’s take a further look at the create method
The next item the create method will do is to check if the blog is valid with the if else statement.
Line 34 says: If the blog is valid, redirect the user to a different page with the message "Blog was successfully created." (In this sense, the create button doesn't just create the blog and leave you at the create page, rather it sends you to the show page and gives you a success message).
Line 37 says: else if the blog is not valid,redirect the user to the new form page so they can create a valid blog.
Note: You do not need to worry about the format.json code. We would use that if we were creating an API. In fact, we can delete the ‘format.json` lines as we're not going to use them so your code will look like this:
There will be no impact on the app whatsoever, and if you like, you can go and check it in the browser.
A Little Rails Magic
You might be wondering how line 35 redirects the user to the right page. That's the magic of Rails. Rails knows by default that when you pass in the @blog
variable, that you should be redirected to the blog show page.
You can also be more explicit and give the path for redirect, like this: ` redirect_to blog_path(@blog)"
However this is unnecessary. My philosophy is the less code you type the less bugs you will introduce into your program. If there is a nice shortcut like this it is good to take advantage of it. Let's revert back to the original code.
After the page redirect, the method is going to give the user a notice.
You can edit the notice if you like(line 31). You could choose to announce 'Your post is now live'
, or anything else that suits the action.
You can test this process by creating a new blog in your browser. You should see your new notice. Later on in the course we will customize the notices so they have a nicer appearance which will lead to a better user experience.
Edit Method
If you understand how new
and create
work, it will be a breeze to understand how edit
and update
work.
Just like new and create are mapped together, edit and update go hand in hand as well. The subtle difference is that edit is for editing an existing item.
Looking at our blogs controller you should note that edit
is in our list of before actions (line 2). That is the reason the method is empty. It has been given the ability to know what item you want to edit.
If you open the edit.html.erb
file, and you'll see the edit form.
def edit end
One nice feature is that this form will be pre-filled with the details of the blog for you. So, the page should look like this:
It is able to display this data because the @blog
variable has made available for you.
Update
Once you click on Update Blog
, the update
action is called. Like the create
page, it will save the updated value to the database and will send you to the show page with a notice that says 'Blog was successfully updated.'
To review: The edit action simply makes the edit form available. The update action does all the actual connections with the database. It does the ‘hard work’ of saving your changes to the database and redirecting your routes.
(Developers note: now is a good time to close your html.erb files and switch back to a single pane view in Sublime with View < Layout < Single)
Just What are blog_params?
There's one thing you may have noticed. In both the create
and update
methods, we have something called (blog_params)
. In general, if you see a standalone word, it means either it's a variable or a method. In this case it's a method, and you can find it line 69 of your blogs controller file.
def blog_params params.require(:blog).permit(:title, :body) end
The blog_params method
is saying that these two parameters: title and body exist and are available in the form. Then it makes them available to the create and update methods so that they can make an instance of blog in the database.
As with create
, let's get rid of the json
code in update
too.
Destroy
The last method we're going to cover in this guide is destroy
. As the name suggests, this method deletes a record for you.
To test, go to your browser, and click on the link called “Destroy”. An alert will pop up asking you if you are sure you want to take this action.
When you hit ok it will delete that item. You will also get a notification that your delete operation was successful and the item was removed.
The Index Action
Open your index.html.erb
file in sublime.
This file contains all the code that creates what you see on the index page in your browser.
You can see on line 1 the code for notifications. When the chosen action contains a notification, that information, such as -The blog was successfully updated' slides into this notice variable.
You can see the title and body in a table format on line 8. You could update the table to say Blog Title
instead of just Title
. Save your file, refresh your browser and you will see that has been updated.
All the actions you can take: show, edit and destroy, are listed as well. These options names can be adjusted to whatever suits your needs.
I do not think I have ever seen anyone leave this destroy
action label. That would usually be updated to say Delete
. But remember, Rails put destroy here to remind you of the workflow and mapping it has built for you.
Let’s change the name of our link in index.html.erb on line 21 from ‘Destroy’
to ‘Delete Post’
. Once again, save your index file and then refresh your browser and you will see the new link name. However the action has remained the same. If you click the link the item will be deleted via the destroy method.
Now go to your blogs_controller.rb file line 55 and update the destroy notice to something a little more friendly such as ‘Post was removed’
.
Go back to your browser and verify that the change has been made by deleting another post. You should see the new 'Post was removed' notification. Now everything is working the way we want it.
Now is a great time to take a break and let your mind process everything we have covered in this guide!