Now that we're able to create our ideas smoothly, let's work on writing code so that users can edit and update the ideas.
First, let's go into ideas_controller.rb. Inside the file, let's add an edit method. In ideas_controller.rb, add the following code right under your create method.
Make sure you don't put it under
private. Code written underprivatewill make the code private, meaning that they won't be accessible outside of the class.
# end of create method
def edit
end
Review on Controller and Views Files
By default, once a controller action is triggered, Rails will try to find a file with the name of the controller action in
app/views/controller_name.For example, when the
editmethod inideas_controller.rbis triggered, Rails will try to find a file callededit.html.erbinsideapp/views/ideas. Review this lesson for more information.
Let's create a file called edit.html.erb in the /app/views/ideas folder.
This edit.html.erb is where we want to put our form for editing ideas. Since we want to be able to tell rails which idea we are editing, let's tell rails to find the idea that we are working on and store that in an instance variable. Let's go back to the ideas_controller.rb and add a line of code to the edit method.
def edit
@idea = Idea.find(params[:id])
end
find
What is this
Idea.find(params[:id])?? This is a new concept, but let's try to break it down into little pieces.First, let's open up our rails console. In the terminal, type in the following command and press enter:
rails consoleOnce it's open, let's type in the following command to display all of our ideas that are stored in the database.
Idea.allAll of your ideas should be displayed in the terminal now. Notice how each idea has it's own
id.When you create an object in Rails, it will give the object a unique
idautomatically. Theseids can be used to retrieve objects.For example, let's say we want to get an
Ideawith anidof1. We can do this with the following command. In the rails console, type in the following command and press enter:Idea.find(1)The code above means: Find an Idea with an id of 1.
The
findmethod can be used to retrieve an object that has theidpassed in as a parameter:Modelname.find(id)Let's go back to this piece of code:
def edit @idea = Idea.find(params[:id]) endHere we see code that we've never seen before:
params[:id]. Let's break down what params are.params
You will see
paramsused in mainly 3 situations.
- GET requests
- POST requests
- Routing parameters
Let's go through each one.
GET Requests
When a user makes a request to a server such as a
GETrequest (refresher on HTTP methods in this lesson, information gets sent to the browser.Many times, the params are encoded in the URL, like this:
http://www.example.com/?foo=1&boo=octopusIn this example, we have two pieces of data,
fooandboo.foois assigned a variable of1andboois assigned a variable ofoctopus.In Rails, we can get the values for each piece of data like this:
params[:foo] # returns 1 params[:boo] # returns octopusPOST requests
When making a
POSTrequest (for example, when you write a Facebook post and hit the submit button), the information will not be encoded in the URL like it did with theGETrequest example above. For example, in our application, we have the following form:<!-- Button trigger modal --> <button data-modal-target="default-modal" data-modal-toggle="default-modal" class="block text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800" type="button"> Add New Idea </button> <!-- Modal --> <div id="default-modal" tabindex="-1" aria-hidden="true" class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full"> <div class="relative p-4 w-full max-w-2xl max-h-full"> <div class="relative bg-white rounded-lg shadow dark:bg-gray-700"> <%= simple_form_for Idea.new do |f| %> <div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600"> <h3 class="text-xl font-semibold text-gray-900 dark:text-white">Add New Idea</h3> <button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-hide="default-modal"> <svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14"> <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/> </svg> <span class="sr-only">Close modal</span> </button> </div> <div class="p-4 md:p-5 space-y-4"> <%= f.input :description, input_html: { rows: 5, class: 'text-gray-800' } %> <%= f.input :author, input_html: { class: 'text-gray-800' } %> </div> <div class="flex items-center p-4 md:p-5 border-t border-gray-200 rounded-b dark:border-gray-600"> <%= f.submit 'Submit', class: 'text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800' %> <button data-modal-hide="default-modal" type="button" class="text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-red-600 dark:hover:bg-red-700 focus:outline-none dark:focus:ring-red-800">Cancel</button> </div> <% end %> </div> </div> </div>Let's say you fill out the form like this:
When a user clicks "Submit", a bunch of data is sent to the server. In your terminal window that is running the rails server, you will see something like this:
Notice how the information we filled out in the form is shown here:
"idea"=>{"description"=>"This is the beginning of a beautiful idea.", "author"=>"Mr. Authy"}These are parameters being sent to the server. We can access these attributes like this:
params[:idea][:description] # returns "This is the beginning of a beautiful idea." params[:idea][:author] # returns "Mr. Authy"Routing Parameters
If we go to our terminal and type
rails routes, you will see a list of routes (review this lesson{:target="_blank"} for more on routes). If you look at theURI patterncolumn, you will see that some have/:id(.:format)at the end of its URI. This:idis important. Rails sends this:idto the server as a parameter.Let's look at an example of the edit action. When we ran rails routes, we see a line like this:
Prefix Verb URI Pattern Controller#Action edit_idea GET /ideas/:id/edit(.:format) ideas#editLet's take a look at the URI Pattern. Notice the
:idportion of/ideas/:id/edit(.:format). This:idrepresents anidthat is passed in as a parameter in the URL.For example, when a user makes a
GETrequest to a URL likehttps://techbrain-ideator.herokuapp.com/ideas/1/edit, theeditaction of theideascontroller is triggered.idis sent to the server as a parameter as well.Overview
Let's take a look at the following code again:
def edit @idea = Idea.find(params[:id]) endNow we know what this means. We are telling Rails to
findtheIdeawith theidofparams[:id], which is a value that is passed in as a parameter, and store it in@idea.
Now let's hop into edit.html.erb. Here we can actually use similar code that we have used before for creating new ideas. Make the file look like this:
<h1 class="text-3xl mb-5 font-bold">Revise Idea</h1>
<%= simple_form_for @idea, method: :patch do |f| %>
<%= f.input :description, input_html: { rows: 5, class: 'text-gray-800' } %>
<%= f.input :author, input_html: { class: 'text-gray-800' } %>
<%= f.submit 'Submit', class: 'text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800 mt-3' %>
<% end %>
The only difference here is that on the first line of the simple form we are adding method: :patch. This piece of code indicates that we are performing a PATCH request. If we type rails routes in the terminal and look at the VERB column, we can see that it corresponds to a controller action. For PATCH, it corresponds to ideas#update. This means that when we submit this form, it will trigger the update method in the ideas controller.
Right now we don't have an update method, so let's add that in our ideas_controller.rb.
Under our edit method, add the following code:
def update
@idea = Idea.find(params[:id])
if @idea.update(idea_params)
redirect_to root_path
else
redirect_to edit_idea_path(params[:id])
end
end
Let's go through what this code is doing. We're first doing the same thing we did in the edit method: finding the idea we are working on using params[:id], and then storing that in @idea.
Then we are saying if @idea updates successfully, then redirect_to the root_path (the home page). If it doesn't update successfully, then redirect_to the edit page that we were just on so that you can enter the correct information.
Why do we need to check if the idea was updated successfully? In the next lesson, we'll talk about validations and get into why we need to do this.