Create a Blog Application with Ruby on Rails 7. Fourth Part: Performing Operations on the Post Resource
In Ruby on Rails Sep 8, 2022
Updated on Dec 17, 2023
In this article, we will implement the ability for users to create, update, delete, and publish 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
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 %>