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 underprivate
will 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
edit
method inideas_controller.rb
is triggered, Rails will try to find a file callededit.html.erb
insideapp/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 console
Once it's open, let's type in the following command to display all of our ideas that are stored in the database.
Idea.all
All 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
id
automatically. Theseid
s can be used to retrieve objects.For example, let's say we want to get an
Idea
with anid
of1
. 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
find
method can be used to retrieve an object that has theid
passed in as a parameter:Modelname.find(id)
Let's go back to this piece of code:
def edit @idea = Idea.find(params[:id]) end
Here we see code that we've never seen before:
params[:id]
. Let's break down what params are.params
You will see
params
used 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
GET
request (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=octopus
In this example, we have two pieces of data,
foo
andboo
.foo
is assigned a variable of1
andboo
is 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 octopus
POST requests
When making a
POST
request (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 theGET
request 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 pattern
column, you will see that some have/:id(.:format)
at the end of its URI. This:id
is important. Rails sends this:id
to 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#edit
Let's take a look at the URI Pattern. Notice the
:id
portion of/ideas/:id/edit(.:format)
. This:id
represents anid
that is passed in as a parameter in the URL.For example, when a user makes a
GET
request to a URL likehttps://techbrain-ideator.herokuapp.com/ideas/1/edit
, theedit
action of theideas
controller is triggered.id
is 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]) end
Now we know what this means. We are telling Rails to
find
theIdea
with theid
ofparams[: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.