Create a Blog Application with Ruby on Rails 7. Second Part: Create a Post Model and a Posts Controller
In Ruby on Rails Sep 5, 2022
Updated on Dec 17, 2023
In this part, we will generate a Post model and a Posts controller and start implementing the relationship between users and posts.
All Parts:
- Create a Blog Application with Ruby on Rails 7. First Part: Create the User Resource
- Create a Blog Application with Ruby on Rails 7. Second Part: Create a Post Model and a Posts Controller
- Create a Blog Application with Ruby on Rails 7. Third Part: Implement User Authentication
- Create a Blog Application with Ruby on Rails 7. Fourth Part: Performing Operations on the Post Resource
- Create a Blog Application with Ruby on Rails 7. Fifth Part: Implement Authorization
create a post model
Let's generate a Post
model with the user_id
as the foreign key. Let's generate in the
terminal the migration file:
bin/rails g model Post title:string content:text status:integer user:references
When the user creates a post, it has a draft
status. Later, when it's finished, the user will publish it,
and its status will change to published
. To achieve that, we use enums
. In Rails, an
enum
is an attribute that maps to integers in the database but can be queried by name.
Let's edit our migration file to set the default for the post status:
class CreatePosts < ActiveRecord::Migration[7.0]
def change
create_table :posts do |t|
t.string :title
t.text :content
t.integer :status, default: 0
t.references :user, null: false, foreign_key: true
t.timestamps
end
end
end
Finally, we run this migration:
bin/rails db:migrate
Let's define the post statuses in the post.rb
in the app/models/
folder:
enum status: {draft: 0, published: 1}
And in user.rb
file we add the has_many
association:
has_many :posts
The corresponding belongs_to
association was automatically added when we generated the Post
model.
create a posts controller
Now, let's generate the Posts
controller. In the terminal, we type:
bin/rails g controller Posts
Before we add methods to our controller, let's use the default resource routing to declare the routes to all the
actions we'll define for the Post
resource. Using the default resource routing, we can declare all the
necessary routes for the index
, show
, new
, edit
,
create
, update
, and destroy
actions. Let's open the
config/routes.rb
file and add these routes:
resources :posts
Let's now start defining these methods in the Posts
controller.
The first method we'll define is the index
method.
Usually, a blog application orders posts by the creation date, so let's do that. Let's first add a method in the
post.rb
file in the app/models/
folder to sort the posts:
def self.by_date
order('created_at DESC')
end
Then, let's add the index
method in the Posts
controller and make use of the
by_date
method:
def index
@posts = Post.all.by_date
end
In the index
view, we will show all posts from all authors. Let's create the index.html.erb
template in the app/views/posts/
folder and add the following code:
<p style="color: green"><%= notice %></p>
<h1>Latest Posts</h1>
<ul>
<% @posts.each do |post| %>
<li><%= link_to post.title, post_path(post) %></li>
<% end %>
</ul>
Let's set the root
route of our application to this index
action. In the
config/routes.rb
file, let's put this at the top:
root 'posts#index'
Next, we will define the show
method, which displays the details of a single post:
def show
@post = Post.find(params[:id])
end
Next, we'll create the corresponding view, show.html.erb
, in the app/views/posts/
folder.
Here, we will show the title of the post, its content, the author, its status, when it was published, and when it was updated:
<p style="color: green"><%= notice %></p>
<article>
<header>
<h1><%= @post.title %></h1>
<p>by <%= link_to @post.user.name, user_path(@post.user)%></p>
<p><%= @post.created_at %></p>
<p>Status: <%= @post.status %></p>
</header>
<p><%= @post.content%></p>
<footer>
<p>Last updated on <%= @post.updated_at %></p>
</footer>
</article>
<p>
<%= link_to "All posts", root_path %>
</p>