A developer using Rails will likely say that they have created a Post resource. In most cases it is meant that a Posts model, a Posts controller with a set of CRUD actions, and some named routes pertaining to that controller (courtesy of resources :posts) were created.
Lets start with resources; resources can be defined as the RESTful syntactic sugar of routes. By using only one line “resources :posts” the rails routing system provides seven different routes mapping to the posts controller actions.
Even thought we have the routes when trying to access the rules return an error. For example if we wanted to display the list of all posts we would have used http://localhost:3000/posts (Assuming the rails server is running and listening on port 3000). The error is pretty descriptive and informative in regards to the missing piece of the puzzle. “uninitialized constant PostsController”, as mentioned each route points to a controller action, in this case rails just informs us that during the HTTP GET request towards the path /posts it tried to access the post’s controller action index, during that action it realized that the post controller is not defined and therefore returned the “uninitialized constant PostsController” as a routing error.
Well, lets fix that! We already know what’s missing so the next step is already clear. Lets create the Posts Controller.
We can generate a Posts Controller using the rails generator named controller. The controller generator can stub out a new controller and its actions, it accepts the name of the controller either CamelCased or under_scored followed by a list of views as arguments.
Therefore in case we would like to generate a Post controller with the index action we would have issued the following command.
Essentially rails will go to controller_generator.rb and by using the template controller.rb it will create the controller using the values we have given to populate the respective variables; seems like rails is doing a lot of work behind the scenes.
By providing generators rails gives us the opportunity to create the vast majority of the code using generators therefore enabling rapid progress towards establishing the base to work from. We can also create our own generators to improve our team’s workflow or customize the existing ones.
Well there’s one alternative that will enable us to understand how to complete the puzzle, using generators creates a lot of files that we will not use in the context of this article.
How about creating the controller manually? By exploring the template rails is using to generate the controller we can pretty much understand what a controller should look like.
So inside our rails app folder under app/controllers we create a new file posts_controller.rb containing the following.
Done! So what happens if we try to access http://localhost:3000/posts?
As per the route /posts rails expects to access the post’s controller index action. Lets go back to the controllers generator syntax;
“The controller generator can stub out a new controller and its actions, it accepts the name of the controller either CamelCased or under_scored followed by a list of views as arguments.”
By exploring the rails controller.rb template with the previous statement in mind it seems that rails defines each view/action as a method; therefore it seems that we should create a method named index in posts_controller.rb.
Done! So what happens if we try to access http://localhost:3000/posts?
The error as the previous one is quite descriptive “Missing template posts/index” since we are accessing /posts the controller is trying to retrieve the view for the index action, seems like the exception has also informed us of the location it searched in for the template so lets head in that directory and create the index template!.
Lets create the view at app/view/posts/index.html.erb (Each controller has its views in a directory using the same name as the controller)
Done! So what happens if we try to access http://localhost:3000/posts?
Finally we have a meaningful response!
By use of the conventions rails enables us to create applications that follow the Model–view–controller (MVC) pattern using a predefined structure. By initiating out application using the “resources :posts” to generate the routes, rails through the conventions has “guided” us towards connecting the routes with a controller, the controller with an action and the action with a view.