DEV Community

Cover image for Under the hood of a scaffold generated controller
Saral Karki
Saral Karki

Posted on

Under the hood of a scaffold generated controller

This week, I have been working on a Todo list app, and for the first time, I used the rails scaffold. This generated a whole host of the required files, routes and codes. I really wanted to understand what was going on in the controller that the scaffold had generated, and so I started reading between the lines and tried unravelling the Rails magic.

First off was the index method in the todo_list controller that had been generated.

def index
 @todo_list = TodoList.all
end

This I thought was straight forward to understand having already completed a project in rails. The entire TodoList model that had been created would get stored in the @todo_list instance. This was a global instance denoted by the@ symbol, which meant I would be able to access the contents from the views as well.

I then opened up my rails console via rails c. Here I wanted to test a few things out for myself. Rails console is a good place to experiment and see what certain syntaxes are actually doing. Upon running the TodoList.all in the console, my understanding of the .all method was verified.

I wanted to see what would happen if I tried to figure out the class of the @todo_list. For this, in my rails console, I ran

@todo_list = TodoList.all
@todo_list.class

The output I received for class type was TodoList::ActiveRecord_Relation.. When working with the model, I have seen this class type many times. There's a lot for me to understand about the ActiveRecord_Relation class, but my basic understanding,I interpreted as:

Looks like activeRecord_Relation as I see in Rails console, stores the data in an array. In my case, something like this

#<ActiveRecord::Relation [#<TodoList id: 1, title: "New todo", description: "Hello this is the first todo", created_at: "2019-02-21 04:51:53", updated_at: "2019-02-21 04:51:53">, 
#<TodoList id: 2, title: "Todo #2", description: "Hello", created_at: "2019-02-21 05:28:20", updated_at: "2019-02-21 05:28:20">]>

Since, the acitveRecord_Relation is an array, I can iterate over it, and display the contents which is exactly what is done in the views. Also, it meant, I could access the elements in the array via indexing. This is exactly what I tried to do next to validate my claim in the console.

TodoList.all[1]
TodoList.all[1].created_at
TodoList.find(1).created_at

I was able to access the second element of the TodoList model with the first syntax. With the second, I was able to look at the created_at time column of the second data. Finally, with the third syntax, I was able to look at the column of the data whose id was 1.

Tip: See the difference between the indexing and using find method which uses id.

There's a lot more to activeRecord_Relation I am sure. My minuscule understanding of it, however, allowed me a glimpse into it. Hopefully, in the future there will be a post on acitveRecord_Relation itself as I understand it better.

Next, I looked at the create method that the scaffold had generated. Something was very intriguing here

def create
    @todo_list = TodoList.new(todo_list_params)

    respond_to do |format|
      if @todo_list.save
        format.html { redirect_to @todo_list, notice: 'Todo list was successfully created.' }
        format.json { render :show, status: :created, location: @todo_list }
      else
        format.html { render :new }
        format.json { render json: @todo_list.errors, status: :unprocessable_entity }

      end
    end
  end

What was intriguing to me was the new method being called at times, and other times I had seen the use of the create method to add entries to the model. My question was "If two method behaved the same way what was the difference between the two?"

I found my answer here.

I then went to the rails console to experiment a bit with the create and new method.

TodoList.new id:4 , title:"Todo 3", description:"What is up?"

This syntax worked and I got no error, however, the data would not be written inside the model. What was happening was using the new method merely instantiated but did not save to the database. In order to save to database, we needed to use the save method in tandem with the new

test = TodoList.new id:4 , title:"Todo 3", description:"What is up?”
test.save

This saved the contents of test into the model TodoList. When we think about it, the new and the save method together work similarly to the create method. However, as described by the stackoverflow answer.

The part of the answer that made some sense to me was

Although it is correct that create calls new and then save there is a big difference between the two alternatives in their return values.
Save returns either true or false depending on whether the object was saved successfully to the database or not. Create will return the model regardless of whether the object was saved or not. This has implications for the code above in that the top branch of the if statement will always be executed even if the object fails validations and is not saved.If you use create with branching logic you are at risk of silent failures which is not the case if you use new + save.

Finally, a new feature introduced to me was the respond_to block. This block allowed me to render my data elements in either standard html format or a json format. For quick verification, in my browser, I entered the .json at the end of my url (localhost:3000/todo_lists/27.json) and got a rendered version of the data in json.

For now, I don't know what to do with this information. What I do know is that json is an important element in web development. Why, and how I will find out as I go along in my coding journey.

Top comments (0)