Create a Blog Application with Ruby on Rails 7. Fourth Part: Performing Operations on the Post Resource

Last updated on September 8, 2022

In this article, we will implement the ability for users to create, update, delete, and publish posts.

All Parts:

  1.  Create a Blog Application with Ruby on Rails 7. First Part: Create the User Resource 
  2.  Create a Blog Application with Ruby on Rails 7. Second Part: Create a Post Model and a Posts Controller
  3.  Create a Blog Application with Ruby on Rails 7. Third Part: Implement User Authentication
  4.  Create a Blog Application with Ruby on Rails 7. Fourth Part: Performing Operations on the Post Resource
  5.  Create a Blog Application with Ruby on Rails 7. Fifth Part: Implement Authorization

First, let’s declare the strong parameters in the private method post_params in the Posts controller:

private

def post_params
params.require(:post).permit(:title, :content, :status, :user_id)
end

Next, we’ll add the new method to the controller:

def new
@post = Post.new
end

 Also, we’ll create the corresponding view, new.html.erb, in the app/views/posts/ folder.

We’ll create a _form.html.erb partial as well because we want to use the same form in both the new and edit views. Let’s create this file and then put this code inside:

<%= form_with(model: post) do |form| %>
<% if post.errors.any? %>
<div style="color: red">
<h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% post.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= form.label :title, style: "display: block" %>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :content, style: "display: block" %>
<%= form.text_area :content %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>

Now, let’s render it in the new.html.erb view. Let’s edit this view as follows:

<p style="color: green"><%= notice %></p>
<h1>New Post</h1>
<%= render "form", post: @post %>
<p>
<%= link_to "All posts", root_path %>
</p>

Let’s put a link to this action on the post index view at the bottom:

<p>
<%= link_to 'Add New Post', new_post_path %>
</p>

Of course, to be able to create a post, we must define a create method. Here we’ll set the post’s user to the user in the session:

def create
@post = Post.new(post_params)
@post.user = current_user
respond_to do |format|
if @post.save
format.html {redirect_to @post, notice: 'Post was successfully created.'}
else
format.html { render :new, status: :unprocessable_entity }
end
end
end

Next, we add an edit method to our Posts controller:

def edit
@post = Post.find(params[:id])
end

Then we create the edit.html.erb view in the app/views/posts/ directory and edit it like this:

<h1>Editing post</h1>
<%= render "form", post: @post %>
<p>
<%= link_to "All posts", root_path %>
</p>

Let’s put a link to the edit action in the show.html.erb file, right before the closing </footer> tag:

<p>
<%= link_to 'Edit', edit_post_path(@post) %>
</p>

Of course, for this form to work, we must define an update method in the Posts controller:

def update
@post = Post.find(params[:id])
respond_to do |format|
if @post.update(post_params)
format.html { redirect_to post_url(@post), notice: "Post was successfully updated." }
else
format.html { render :edit, status: :unprocessable_entity }
end
end
end

Next, we will implement the ability to delete posts. Let’s define a destroy action in the controller:

def destroy
@post = Post.find(params[:id])
@post.destroy
redirect_to root_path
flash[:notice] = 'Post was successfully deleted.'
end

And in the post show view, below the link for editing the post, let’s add a delete button:

<%= button_to "Delete", @post, method: :delete %>

Finally, let’s add a publish method to the controller:

def publish
@post = Post.find(params[:id])
@post.published!
redirect_to post_path(@post)
flash[:notice] = 'Post was successfully published.'
end

Then we define a route to the publish action. Let’s open the config/routes.rb file and edit the post resource block like this:

resources :posts do
member do
get :publish
end
end

Last thing we’ll do is to add a publish button in the post show view below the delete button:

<% if @post.draft? %>
<%= link_to 'Publish', publish_post_path(@post) %>
<% end %>