Prerequisition
You have already installed rbenv
and familiar with the command.
This project was made based on Progate
Generate New Project
Create new folder like mkdir new_project
and go inside cd new_project
. Set local for ruby version 2.7
using rbenv local 2.7
. Then generate new project by using command rails _7.0.3_ new kicau
.
Go to kicau
dir, and run server using rails s
Put this address http://localhost:3000/
on browser and you’ll see Rails welcoming screen if success.
Create Homepage
Create the top page with rails generate controller home top
.
A new web page is automatically created by this command, and will allow you to access localhost:3000/home/top
. Well, when you run the command, Rails generates all the necessary files for displaying page. To display a page in Rails, you need the three things shown below:
- View
- Controller
- Route
Understanding View
A view is an HTML file that’s used to create the look of a page. When the browser asks for a file, Rails returns a requested view to the browser to display a page. Views are located inside the views folder. The rails generate controller home top
command generates the home
folder and a file named top.html.erb
in the views folder. erb
is a unique file format, but you can think of it as a regular HTML file for now.
Because a view (HTML) contains the content displayed in the browser, you can change the content by editing the file. Let’s edit top.html.erb
to make it look more like the Top page of TweetApp.
In the view for the Top Page (app/views/home/top.html.erb)
|
|
Open the browser and check localhost:3000/home/top
!
Understanding Controller
When displaying a page, Rails returns views via its controllers. Let’s take a look inside a controller file. The rails g controller home top
command creates creates a controller file named home_controller.rb
with a top
method. A method within a controller is also known as action
.
The role of an action in a controller is to find a view from the views
folder, then return it to the browser. The action looks for a folder with the same name as controller (Home
), then finds a file with the same name as the action (top
)
Understanding Route
While we return the view through the controller, the routing is the one reponsible for connecting the browser to the controller. Make sure to understand that the process for displaying a page is in the following order: routes -> controllers -> views.
Routes can be described with a routing table
. A route points to a specific action of a controller according to the URL requested. When a URL is entered in the browser, it calls for a matching action in the controller based on the URL.
Routes are defined in the config/routes.rb
file in the following syntax: get "URL" => "controller#action
. For instance, as shown in the image below, the URL “localhost:3000/home/top” points to the top
action in the Home controller.
We can practice to change route of the Top page. Once you modify the route, you can access the Top page via localhost:3000/top
by changing get "home/top" => "home#top"
to get "top" => "home#top"
.
Create About Page
Let us create the about page. But now we can use again rails generate controller
. The command we inputted when we created the Top page actually contains controller name
and action name
. The rails generate controller controller_name action_name
command generates a controller and the files associated with it. However, you can’t use this command when a controller with the same name exists.
To add about
page, we do manually.
- In Routes file, routes.rb, Add
get "about" => "home#about"
- In home_controller.rb file, inside class HomeController, add action for
about
and left it empty. - In the
app/views/home/
, add file calledabout.html.erb
, and put some words in html format.
Create Posts
Let’s create an index action for the Posts page. Since the Posts controller doesn’t exists yet, we can use the command like rails g controller posts index
. We’re going to write the HTML for the Posts page in views/posts/index.html.erb
. First, let’s copy & paste the provided code to quickly create a page.
Feature
These are four common features of post:
- View all posts -> use action
posts#index
to view all posts - Show detail post -> use action
posts#show
to view detail post - Create post -> use action
posts#new
andposts#create
to view create new post form and sending the form data. - Edit post -> use action
posts#edit
andposts#update
to view edit form and sending the updated form data. - Delete post -> use action
posts#destroy
to delete post record
Preparing a Database
A database consists of tables. Each table has rows and columns. In the posts
table shown below, each row also known as a record
, represents a post while each column represents a specific type of data.
To store data in a database, we need to create a table like the one in the last slide. Let us create the posts
table for storing posts. There are two steps we must follow, i.e.
- Create a file that directs the changes to the database
- Apply the changes in the database
Create a Migration File
We need to create a migration file to make changes to the database. With the rails g model Post content:text
command, you can create a migration file which adds the posts table with the content column. The text
describe the type of data that will be stored in the column.
Look again rails g model ..
command. The Post
in the command represent a model name. With this command, the following files are generated:
- a file in app/models where a model is defined
- a migration file in db/migrate
Create a Table
In this step, we will apply the changes to the database using the migration file we have created. To apply the changes in the database, simply execute the command rails db:migrate
. By executing the command, it will create a table according to the code in the migration file.
Adding Data to a Table
Let’s create an instance of Post from the Post model (Post class) in the rails console
. To create an instance, we’re going to use the new
method. For example, you can create a Post instance with the content, “Hello World”, post = Post.new(content: "Hello World")
.
To save a Post instance to the posts table, you need to run the save
method, post.save
. Because the Post model inherits from ApplicationRecord, it can use the methods defined in ApplicationRecord, like the save
method.
We can get the first record in the posts table using post = Post.first
. Then with post.content
, we can get the content of the first post. To get all the data from the posts table, use post = Post.all
which returns you all the data saved in the table in the form of an array. Then we can get an element using an index number like Post.all[0]
. The data we get with Post.all[0]
is the same as data you get with Post.first
. So with Post.all[0].content
, you can get the content of the first post.
Displaying Error Message
Rails provides a special flash
variable. By assigning a string to flash[:notice]
in an action, you can use flash[:notice]
in the views. Flashes are automatically removed after being displayed once. We’ll add flash[:notice]
to application.html.erb
because it’ll be used in many places.
We put these lines after closing tag </header>
|
|
Adding Routes
By writing posts/:id
with a colon :
in the URL of the route, you can map URLs like /posts/1
and /posts/2
to the show
action. This applies to every URL written as /posts/...
. In routes.rb
, write
|
|
It’s important that you need to write the route posts/:id
below posts/index
and posts/new
. This is because the routing looks for URLs from the top. Writing it above posts/index
or posts/new
would cause the URL localhost:3000/posts/index
or localhost:3000/posts/new
to match the route posts/:id
.
Generally, when you press the submit button, the post data will be sent to the server-side (Rails). Let’s prepare a create action to save the receive post data to the database. The URL of the create
action should be /posts/create
. We use post
method on the create
when receiving data from a form.
Since the update
action receives the value from the form, we also need to change the routing to post
instead of get
. It is also updates the post with a specific id, so make sure to include id
in the URL.
Adding Action
Let’s adding some actions in the Post Controller. In the index
action of the Post controller, We catch the data from the database using Post.all
, then assign them to @posts
variable. In posts/index.html.erb
, we can use the each
method to loop through the @posts
array to print each post.
In the show
action, the value of the :id
is stored in a hash variable known as params. You can get that value using params[:id]
. To display the post, we declare the variable @post
in the show
action and assign it the posts whose id
is equal to params[:id]
by retrieving them from the database. Then we’ll display the details of the @post
in ‘show.html.erb`.
Since new.html.erb
will also be displayed via new
action (localhost:3000/posts/new), an error will occur unless we also define the @post
variable there. We can solve this by assigning Post.new
(a blank post instance), to @post
as code shown above.
|
|
There are two problems for creating action:
- No matching view for the create action.
- Can’t save any posts.
For solving this problem, we can redirect to a different URL instead of adding a view. For our create
action, let us redirect the request to the Posts page.
|
|
To solve second problem, we have go to two steps:
- Send post data to the create action
- Receive the sent data in create action and save it
To send data to the create action, We need to specify the name
attribute of the <textarea>
tag. This way, the data in the <textarea>
tag will be sent to the Rails side as a hash
with the name
attributes as the key.
Once you specify the name attributes of a form element, the action of the controller can receive the form data. Since the params
variable is a hash with the name attibutes as the key, we can get content with params[:content]
.
To receive the sent data in the create action, we can create a @post
with the data received from the form by using params[:content]
as the argument.
|
|
We’ve used params when receiving input data and also to get the id
value from the URL. Remember there are two ways of using params:
- Get the value from the URL of the route
- Get the form input data with the
name
attribute
Adding Views
In the views/posts
folder, we need to create
new.html.erb
is html page to display create-post formindex.html.erb
is to view all postsshow.html.erb
is to show detail postedit.html.erb
is to display post-edit form
New Post
You can send the data entered in the form using the form_tag
method. The destination URL is specified like: <%= form_tag(destination URL) do %>
. This allows <input type="submit" ...>
, also known as the submit button in the form, when clicked, for the data to be sent to the specified URL.
Put these lines to posts/new.html.erb
,
|
|
Displaying All Post
In posts/index.html.erb
, we can use the each
method to loop through the @posts
array to print each post.
|
|
Displaying Detail Post
Then in the /posts/show.html.erb
, put these
|
|
In ’erb’ (or Embedded Ruby) file format like ‘index.html.erb’, you can embed Ruby code in HTML using <% %>
brackets.
Let’s try to assign and display a variable called ‘post1’. Put this code in an ‘html.erb’ file format.
|
|
We’ve learned that we can <% %>
and <%= %>
to embed Ruby code. <% %>
is used in cases like defining a variables as it won’t be displayed. <%= %>
on the other hand, is used for cases like printing the content of a variable as it will be displayed.
Edit Form
We’ll able to edit and delete posts from the Post details
page as shown in the left image. We’ll also create an Edit post
page to edit posts as shown in the right image.
Let’s add an Edit
and Delete
links in show.html.erb
as shown below
|
|
You can send a post
request with link_to
method by adding {method: "post"}
as the third argument.
The data of the form needs to be sent to the update
action in order to be saved to database. Just like with the New post page, you can specify the destination using the form_tag
method. In the posts/edit.html.erb
, put these lines
|
|
where <%= @post.content %>
in line 15 is the initial value.
Post Validation
Validation is set in the models/post.rb
as shown in codes below.
|
|
You can use the validates
method, and specify the column name and the details of the validation as arguments. By using {presence: true}
as shown below.
|
|
Validation can be used to check not only the existence of a value but the number of characters as well. As shown in the image, We can set the maximum number of characters using
|
|
The list of validation rules, known as validators
, is actually a hash. You can specify more than one by separating them with a comma ,
as shown below
|
|