If we look back at our wireframes, we see that we still have to build out the "About" and "Random" page. To give you a refresher on what we are trying to build here, the "About" page will be a page that will be used to describe what the web page is all about. The "Random" page will be a page that displays an idea that will be chosen randomly.
To create these new pages, let's create a new controller called static_pages
. In the terminal, let's type in the following command:
rails generate controller static_pages
This should generate the static_pages
controller. Inside this controller, we are going to create two methods, the about
method and the random
method.
In your static_pages_controller.rb
file, let's add in the following lines:
class StaticPagesController < ApplicationController
def about
end
def random
end
end
We will see why we set up these routes in a bit, so hang tight.
Next, let's set up some routes
for these pages.
Let's go into our console and type rails routes
to display our routing.
Prefix Verb URI Pattern Controller#Action
root GET / ideas#index
ideas GET /ideas(.:format) ideas#index
POST /ideas(.:format) ideas#create
new_idea GET /ideas/new(.:format) ideas#new
edit_idea GET /ideas/:id/edit(.:format) ideas#edit
idea GET /ideas/:id(.:format) ideas#show
PATCH /ideas/:id(.:format) ideas#update
PUT /ideas/:id(.:format) ideas#update
DELETE /ideas/:id(.:format) ideas#destroy
We see that we don't have any paths that we can use for the "About" and "Random" pages. Let's go ahead and set these up.
Let's go into our routes.rb
file, which is where we can specify how the pages are routed, to hook up our new pages.
Right now, we only have two lines, root 'ideas#index'
and resources :ideas
. If we recall, root 'ideas#index'
sets the root page, or the home page, to the index action of ideas. Additionally, resources :ideas
automatically provided us with a bunch of useful links that we could use.
View this lesson to review what
resources
do in theroutes.rb
file.
For the "About" and "Random" pages, we need to add these routes in manually. To do this, under resources :ideas
, add the following lines:
get 'about' => 'static_pages#about'
get 'random' => 'static_pages#random'
Let's run the rails routes
command.
Prefix Verb URI Pattern Controller#Action
root GET / ideas#index
ideas GET /ideas(.:format) ideas#index
POST /ideas(.:format) ideas#create
new_idea GET /ideas/new(.:format) ideas#new
edit_idea GET /ideas/:id/edit(.:format) ideas#edit
idea GET /ideas/:id(.:format) ideas#show
PATCH /ideas/:id(.:format) ideas#update
PUT /ideas/:id(.:format) ideas#update
DELETE /ideas/:id(.:format) ideas#destroy
about GET /about(.:format) static_pages#about
random GET /random(.:format) static_pages#random
Notice how in the last two lines, the routes for the about
and random
page were added.
Now what will happen is, when a user goes to a URL with the /about
URI pattern, it will trigger the about
action in the static_pages
controller. Similarly, when a user goes to a URL with the /random
URI pattern, it will trigger the random
action in the static_pages
controller.
Now that we've set up these routes, let's go into our controller and set up the view for these two routes in the next lesson.
Under /app/views/static_pages/
make a file called about.html.erb
.
This is just going to be a static page, so you can put any kind of text here. For me, I just put in a bunch of filler text for now, but it looks like this:
<h1 class="mb-5 text-4xl font-bold">About</h1>
<h4 class="mb-3 text-2xl font-bold">Share your ideas with the world and find others.</h4>
<p class="mb-3">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p class="mb-3">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p class="mb-3">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
How to Add Filler Text
Adding filler text can be incredibly useful when you want to put content in the HTML to see what it would look like with content. To generate the classic filler text "Lorem ipsum...", you can go into Sublime, start typing
lorem
, and then hittab
. Just like that, your "lorem ipsum" text should be generated.
Now let's add the link to this page on the navigation bar so that people can navigate to the about page easily. Go to application.html.erb
.
By now, you should have a grasp on how link_to
works in rails. Try and see if you can generate the link yourself.
Your navigation bar should now look like this:
<nav class="bg-white border-gray-200">
<div class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-1 md:p-4">
<a href="/" class="flex items-center space-x-3 rtl:space-x-reverse">
<span class="self-center text-2xl font-semibold whitespace-nowrap font-pacifico text-[30px] tracking-[2px] text-primary-500">Ideator</span>
</a>
<button data-collapse-toggle="navbar-default" type="button" class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200" aria-controls="navbar-default" aria-expanded="false">
<span class="sr-only">Open main menu</span>
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 17 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h15M1 7h15M1 13h15"/>
</svg>
</button>
<div class="hidden w-full md:block md:w-auto" id="navbar-default">
<ul class="font-medium flex flex-col p-4 md:p-0 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:flex-row md:space-x-8 rtl:space-x-reverse md:mt-0 md:border-0 md:bg-white">
<li>
<a href="#" class="block py-2 px-3 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0" aria-current="page">All Ideas</a>
</li>
<li>
<a href="#" class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0">Inspire Me</a>
</li>
<li>
<a href="/about" class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0">About</a>
</li>
</ul>
</div>
</div>
</nav>
Let's try this out. If you go to /about
, you should see your about page. Awesome!
Let's now move on to building the "Random" page.
Now that we've got the "About" page, let's add the final page - the "Random" page. On this page, we want to display one random idea from our database, and everytime a user refreshes the page, we want it to generate another random idea.
For the first few steps, let's do exactly what we did for the about page.
We're first going to create a file called random.html.erb
inside /app/views/static_pages
.
Then we're going to go into our static_pages_controller.rb
and add the random
method. In this method, we're going to try to store a random Idea
into an instance variable so that we can use it in our random.html.erb
.
It turns out that you can do this easily by doing this:
@idea = Idea.all.sample
What we are doing here is first ordering all of our ideas randomly. Then we are grabbing the first idea off of the randomly ordered ideas, and then storing it into @idea
.
Let's now add modify the random
method to in the static_pages_controller.rb
to look like this:
def random
@idea = Idea.all.sample
end
Like we've explained before, with this method called random
, we can now use the instance variable @idea
in our views
. With this piece of code, @idea
will now give us a random idea, so let's go into our random.html.erb
and display this. In random.html.erb
, add the following piece of code:
<%= @idea.description %>
<%= @idea.author %>
Here, we are displaying the description
and author
of the @idea
. Remember, here @idea
is assigned a random Idea
.
If we go to /random
, we see an idea and every time we refresh the page, a new idea comes up. Awesome!
Now we just want to put this in a card panel, like we did on the index page. We're just going to pull the code from index.html.erb
and tweak it a little bit. Replace the code in random.html.erb
with this:
<div class="rounded overflow-hidden shadow-lg">
<div class="px-6 py-8 h-full">
<div class="font-bold text-xl mb-2"><%= idea.description %></div>
<p class="text-sm text-gray-700"><%= idea.author %></p>
<div class="mt-4">
<%= link_to 'Delete', idea_path(idea), method: :delete, 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', data: {confirm: "Are you sure?"} %>
<%= link_to 'Revise', edit_idea_path(idea), 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' %>
</div>
</div>
</div>
If we refresh the page, we see that it's nicely displayed now.
There's one little gotcha for this page though. The page will actually give us an error that the @idea
is nil
if we don't have any ideas yet. This isn't good and it means that we need to tinker with the code here.
What we can do is use an if else
statement and say, if @idea
is present, then we display the button and the random idea, otherwise display some message saying there are no ideas.
We can actually do this pretty simply in our views.
<% if @idea.present? %>
<h1 class='mb-5 text-2xl font-bold'>Inspire Me</h1>
<div class="rounded overflow-hidden shadow-lg">
<div class="px-6 py-8 h-full">
<div class="font-bold text-xl mb-2"><%= idea.description %></div>
<p class="text-sm text-gray-700"><%= idea.author %></p>
<div class="mt-4">
<%= link_to 'Delete', idea_path(idea), method: :delete, 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', data: {confirm: "Are you sure?"} %>
<%= link_to 'Revise', edit_idea_path(idea), 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' %>
</div>
</div>
</div>
<% end %>
Conditionals in the Views
We've talked about how we can use
<%= %>
and<% %>
to embed ruby code into ourerb
files.In the code above, we used an
if
statement in theerb
file. This is just another example of ruby being used inside theerb
file. It works just like ruby, if a condition is true, the HTML code inside of the block is displayed, otherwise, it is not.
Sweet, you've now added all of the pages successfully! The final step in this lesson is to add a link to the random page in the navbar.
Go to application.html.erb
in Sublime and above the link to the "About" page, add the "Random" page link. I named my page the "Inspire Me" page, just because it sounds cooler :D
Again, let's try to generate this link yourself. A hint is to look into your rails routes
!
If you did it correctly, it should look like this:
<nav class="bg-white border-gray-200">
<div class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto p-1 md:p-4">
<a href="/" class="flex items-center space-x-3 rtl:space-x-reverse">
<span class="self-center text-2xl font-semibold whitespace-nowrap font-pacifico text-[30px] tracking-[2px] text-primary-500">Ideator</span>
</a>
<button data-collapse-toggle="navbar-default" type="button" class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200" aria-controls="navbar-default" aria-expanded="false">
<span class="sr-only">Open main menu</span>
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 17 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h15M1 7h15M1 13h15"/>
</svg>
</button>
<div class="hidden w-full md:block md:w-auto" id="navbar-default">
<ul class="font-medium flex flex-col p-4 md:p-0 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:flex-row md:space-x-8 rtl:space-x-reverse md:mt-0 md:border-0 md:bg-white">
<li>
<a href="#" class="block py-2 px-3 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0" aria-current="page">All Ideas</a>
</li>
<li>
<a href="/random" class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0">Inspire Me</a>
</li>
<li>
<a href="/about" class="block py-2 px-3 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0">About</a>
</li>
</ul>
</div>
</div>
</nav>
Congratulations! You've now officially built a fully functional app! The next few steps will be the final touches to get your app fully in shape :)
After going through the standard git workflow, let's deploy all of the new changes that we have made to Heroku.
git push heroku master
Every time we push to Heroku, we should run migrations on the production server:
heroku run rails db:migrate
Then we should restart the server:
heroku restart