Rails! Here I come (Day #3)
Tags: rails, beginners, writing, webdev
Published: 2019-01-30 16:03:29

---
title: Rails! Here I come (Day #3)
published: true
description: On day three, I created a form and dynamically fetched data to view
tags: rails, beginner, writing , webdev
---

Starting from where I left off yesterday. I had manually entered data to the database and fetched the data for viewing. Today, my goal was to take it up a notch and enter data on a form and fetch this data for viewing. 

I could have used the `resources` available on rails, but because I wanted to create my first posts page from scratch I chose to manually create all the controllers and routes. 

### 1. Building a mental picture
I started off by building a mental picture of what was required. I would need a route with get verbs(`get` method) for redirecting to post pages, and I would need a post verb(`post` method) for saving the user input data to my database. I would be using the same database `Post` that I created yesterday. With a quick `Post.delete_all` in my rails console, I wiped my database clean. 

Next up, I made the routes ready in route.rb. I would need a `/post/index` route to view all the posts from the database (just the titles), `posts/new` would route to the form, and `posts/:id` would route to a show page that would display the texts of the post in its entirety. I also used an `as` command to change the prefix of the of `posts#new` to `new_post` and `posts#show` to `post`. These will be very helpful later on. I also changed the homepage for this exercise. My `posts/index` would be my homepage. I also would need a `post` method to fetch user inputs from the forms. 

```
Rails.application.routes.draw do
get 'posts/index'
root 'posts#index'
post 'posts' => 'posts#create'
get 'posts/new'  => 'posts#new' as: 'new_post'
get 'posts/failure' => 'posts#failure` , as: 'failure'
get 'posts/:id' => 'posts#show', as: 'post'

end

```
#### TIP: Remember to `get` all the methods for `posts` before `posts/id` else what rails will do is start treating the actions such as `new`, `failure` as `id`, and when such id cannot be found (because they do not exist), rails throws an error.

### 2. Setting up Controllers

   I had already generated the posts controller yesterday via `$rails g controller posts`. Therefore, I set forth on making updates to the controller. 
First I defined the index function where all the contents of my database would be displayed as per the need. Next I defined the actions`new`, and `show` in the `posts` controller as per my route. Finally, I had to set up action for `create`.

```
class PostsController < ApplicationController
    
    def index  
        @posts = Post.all   
    end

    def show
        @post = Post.find(params[:id])
    end

    def new
        @post = Post.new
    end
       
    def create
        post = Post.new(post_params)
        if post.save
            redirect_to post_path(post)           
        else
            redirect_to new_post_path          
        end
    end

    private 
        def post_params
            params.require(:post).permit(:title,:blob,:author)
        end
end

```
  * Breaking down each action

       * The index action as described yesterday gets all posts from the Post database, and stores it in the instance @post, so that it can be later used in the views.

       * The show action searches and finds from the database the `:id`. This `param[:id] is generated from the routes. 

       * the new action (here I am merely guessing) fetches data from the form, and stores it in the instance @post. This data is now ready to be saved to the database. It has not yet been written to the database, however, we have received the data from the form in the new page. So, I did a quick check in my console after I commented the code on the `create` action.




            Processing by PostsController#create as HTML
            Parameters: {"utf8"=>"✓",             
              "authenticity_token"=>"z7vZT7ReRs6LKg5bJuGgnMTuEzYwbDbdDvZmi+HAf2CCNICj2CEm/uxPX6Z            WqqEy0GPMLLGLL//Bl+BT/D38kQ==", "post"=>{"title"=>"Introduction",     "blob"=>"Hello World. How are you?", "author"=>"Saral"}, "commit"=>"Submit"}
            No template found for PostsController#create, rendering head     :no_content
            Completed 204 No Content in 56ms (ActiveRecord:          0.0ms)





          Let me try and break this down, I can see that the title, blob(or body) and author is being committed to submit. However, then it throws an error saying No templated found for `PostsController#Create`. This gives me an indication that I need to render a template in `PostsController#create`.


       * Finally, in the create action is where the magic happens. Here I declared a private function that defined the params for posts as `post_params` (need to understand this better). The params use the method .require and says it needs a post from the database, and only permits input from the title, blob(body) and author from the forms and saves only these into the database. One reason this is used is for security measures. With this in place, SQL injection can be prevented, and malicious users cannot post useless and harmful stuff to the database.             
       After this is done, the create action fetches the post_params as defined on private. It then checks the condition, if the post was saved successfully it redirects to the post_path. If you recall the post_path is the posts/:id page. Therefore, we get redirected to a page `posts/1`. The '1' is a dummy id in this case. The id will keep changing as the number of items on our database grows. Finally, if the data is unable to be written to our database we redirect to a failure page.  
      Once all this was done, and my view set up accordingly, I was able to send my data to my view page from the forms. 
       
But, wait how do we set up the views? How do we make a connection between the backend and frontend?

### 3. The Views

 * Setting up the new page


        <div class="container">
        <div class = "row">
        <div class="col-md-12 post_heading">
            <h1> Your blog post goes here </h1>
        </div>
        </div>
        <div class="row">
        <div class="col-md-12">
            <%= form_for(@post) do |f|%>
                <div class="form-group">
                    <%= f.label :title %><br>
                    <%= f.text_field :title , class: "form-control" , placeholder: "Title" , :required => true %>
                </div>
                <div class="form-group">
                    <%= f.label :blob, 'Story' %><br>
                    <%= f.text_area :blob , class: "form-control blog_body" , rows: 20, :required => true %>                  
                </div>
                <div class="form-group text_size">
                    <%= f.label :author %><br>
                    <%= f.text_field :author , class: "form-control"%>
                </div>
                <div id = "btn">
                    <%= f.submit "Submit", class: "btn btn-primary" %>
                </div>
             <% end %>           
        </div>
    </div>
</div>



   Noteable observation here is the embedded ruby code for generating the form alongside your regular html/css. We are using `form_for` method to get the variable @post. Recall, how we set up in our controller `@post = Post.new`. We are using that very variable to save the title, blod(body) and name of the author. Also, notice how I have used bootstrap classes to the ruby code. The final page looked like this

  ![Alt New Post View](https://i.postimg.cc/HnHpWyML/newpost-at-9-38-42-PM.png)

   Finally, as using a similar html view as yesterday's `index.html` I was able to fetch and view the data.

        <div class="container">

        <h1> Post List </h1>
        <table class="table">
        <thead class="thead-dark">
        <tr>
            <th scope="col"> Title </th>
        </tr>
        </thead>
        <% @posts.each do |post| %>
        <tr>
            <td> <%= link_to post.title, post_path(post) %> </td>
        <% end %>  
        </table>
        </div>



![Alt Final Image](https://i.postimg.cc/3wnjFXKs/Screen-Shot-2019-01-30-at-9-43-03-PM.png)

 

    
 Final words, there's a lot to unpack from what I did today,but overall I think this post sums it up. I could write a lot more about views and controller,but I feel I will be able to explain things better as I go forward in this coding and writing journey. 

Tomorrow, we tacklet updating and deleting posts. Also, if time permits we look into user database and registration.