Creating Simple Blogging Platform - Editing Posts

By:, On:

This tutorial assumes you have already completed:

  1. Install Ruby on Rails
  2. Create Ruby on Rails application
  3. Create Static Pages - without this deploy will not work
  4. Install Git
  5. Create Remote Git Repository - optional but recommended
  6. Deploy application to Heroku
  7. Manage users with Devise
  8. How to add Twitter Bootstrap to Ruby on Rails application - Advised
  9. Creating Simple Blogging Platform - Creating Model
  10. Creating Simple Blogging Platform - Routes
  11. Creating Simple Blogging Platform - Displaying Posts
  12. Creating Simple Blogging Platform - Building Posts

Once we've created posts, it's time to allow our users to edit their posts.

Step 1: Edit Action

We'll start by defining new action in the controller:

app/controllers/posts_controller.rb


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

private

We're using params[:id] the same way as when we were looking for the post to show up. This time, however, we want to make sure the owner of the post is the only one allow to have access and make changes to his/her post.

app/controllers/posts_controller.rb


def edit
   @post = Post.find(params[:id])
   redirect_to posts_path unless @post.user == current_user
end

Step 2: Create New html File

Now, we can create an HTML page that matches th action's name. Inside posts folder, create a new file and call it "edit.html.erb". Add the code below:

app/views/posts/edit.html.erb


<%= form_for @post do |f| %>
        <%= render 'shared/error_messages', object: f.object %>
        <div class="form-group">
            <%= f.label :title, class: 'control-label' %>
            <%= f.text_field :title, class: 'form-control' %>
        </div>

        <div class="form-group>
            <%= f.label :body, class: 'control-label' %>
            <%= f.text_area :body, class: 'form-control', rows: 6 %>
        </div>

        <%= f.submit 'Save', class: 'btn btn-primary %>
<% end %>

You have probably noticed, that this form looks identical to the new.html.erb . In order to keep our code DRY (don't repeat yourself). We will extract this form into a partial which we can later render on both new and edit pages. In app/views/posts/ create new file and call it "_form.html.erb".

app/views/posts/_form.html.erb


<%= form_for post do |f| %>
        <%= render 'shared/error_messages', object: f.object %>
        <div class="form-group">
            <%= f.label :title, class: 'control-label' %>
            <%= f.text_field :title, class: 'form-control' %>
        </div>

        <div class="form-group>
            <%= f.label :body, class: 'control-label' %>
            <%= f.text_area :body, class: 'form-control', rows: 6 %>
        </div>

        <%= f.submit 'Save', class: 'btn btn-primary' %>
<% end %>

Make sure you change "@post" to "post"

Step 3: Replace Old Form in New Files

Now, we can replace the old form in new and edit with single line pointing to the partial:

app/views/posts/new.html.erb


<h1>New Post</h1>
<%= render 'form', post: @post %>

app/views/posts/edit.html.erb


<h1>Edit post</h1>
<p><%= link_to 'back', post_path(@post) %></p>
<%= render 'form', post: @post %>

Also, let's add link to edit page in "show" template. In between the tag h1, add from line 3 to line 6:

app/views/posts/show.html.erb


<h1>
        <%= @post.title %>
        <% if @post.user == current_user %>
            <small><%= link_to 'edit', edit_post_path(@post) %></small>
        <% end %>
</h1>
<p><small><strong>By: </strong><%= @post.user.email %></small></p>
<p><%= @post.body %></p>

We can add this code using more concise short hand version with content_tag. Although, I believe it might be a little confusing at the beginning.

app/views/posts/show.html.erb


<h1><%= @post.title %> <%= content_tag(:small, link_to('edit', edit_post_path(@post))) if @post.user == current_user %></h1>
<p><small><strong>By: </strong><%= @post.user.email %></small></p>
<p><%= @post.body %></p>

Step 4: Update action

Our editing feature almost done. However, it's unable to save in the data base all the changes we submit in edit form. To maintain those changes we will use "Update" action.

In projects controller:

/app/controllers/posts_controller.rb


class PostsController < ApplicationController
# existing code

def update
        @post = Post.find(params[:id])
        if @post.user == current_user
            if @post.update_attributes(allowed_params)
                flash[:success] = "Updated post"
                redirect_to @post
            else
                render 'edit'
            end
        else
            redirect_to posts_path
            flash[:notice] = "You can't to this"
        end
end


private
        def allowed_params
            params.require(:post).permit(:title, :body)
        end
end

As you can see the code is similar to the "create" action, however this time, we need to check if the owner of the post is the current_user. Also, instead of building new post we uptate_attributes.

Notice how both create and update actions don't have their own HTML templates. We simply redirect the user after we perform the work.

Go ahead and take it for a spin.

Deleting posts

If you login you will be able to mark this tutorial as finished to track your progress



Comments

  • On: nate wrote:

    There is a missing '

    app/views/posts/edit.html.erb

    <%= f.submit 'Save', class: 'btn btn-primary %>

  • On: nate wrote:

    app/views/posts/_form.html.erb is missing "

Comment

You can login to comment