Implement Draft & Publish to Rails

Let’s say you have a

model in your Rails app and you want to be able to toggle between ```draft``` and ```publish``` statuses. When your blog is in the ```draft``` staus you don't want it seen by the by the ```public```. In other words visitors to your blog will only be able to see your ```published``` blogs. Assuming you already have a ```blog``` model in your Rails app, you might even call this model ```post```, or ```article```, the name doesn't matter. In my case I have a ```blog``` model in ```app/models/blog.rb``` and to it, I would like to add the ```draft``` and ```publish``` statuses. Below are the steps I will take to accomplish this. Note, this post assumes you're on a ```Rails 5``` app, if you are on a ```Rails 4x``` app or below replace ```$rails``` with ```$ rake``` accordingly, when you run your commands below.
1
2
3
4
5

- First step is to run the following migration to add the ```status``` column to your blog model or any such model in your case.

```bash
$ rails g migration add_status_to_blogs status:integer

  • Your second step is to add the

    value``` e.g. ```0``` to the migration you just created before you run the migration.
    1
    2
    3
    4
    5
    6
    7

    ```ruby
    class AddStatusToBlogs < ActiveRecord::Migration[5.0]
    def change
    add_column :blogs, :status, :integer, default: 0
    end
    end

  • Third, run the migration as shown below.

1
$ rails db:migrate
  • The fourth step is to open and update the blog model, or the model you’re working on.
1
2
3
4
5
6
7
class Blog < ApplicationRecord
enum status: { draft: 0, published: 1 }
.
.
.

end
  • Fifth lets hope into the
    console``` to test and make sure everything is working as it should be so far.
    1
    2
    3

    ```bash
    $ rails console
1
> Blog.first
  • In the sixth step, lets use the bang ! to publish the first blog as shown below.
1
> Blog.first.publish!
  • Seventh, lets use the bang

    to publish the last blog as shown below.
    1
    2
    3

    ```bash
    > Blog.last.publish!

  • Eight, check to see if the blog is in the draft? status.

1
> Blog.last.draft?
  • Ninth, check to see if the blog is in the published? status.
1
> Blog.last.published?
  • Tenth, update the blog index page and add the status link in app/views/blogs/index.html.erb.
1
<%= link_to blog.status, toggle_status_blog_path(blog) %>
  • Eleventh, open your routes.rb file and add the toggle_status route.
1
2
3
4
5
6
7
8
9
10
11
Rails.application.routes.draw do
root to: 'pages#home'
.
.
.
resources :blogs do
member do
get :toggle_status
end
end
end
  • Twelfth, open your blogs_controller.rb file and add the toggle_status method.
1
2
3
4
5
6
7
8
9
def toggle_status
if @blog.draft?
@blog.published!
elsif
@blog.published?
@blog.draft!
end
redirect_to blogs_url, notice: 'Your blog was successfully updated.'
end

If you have any questions or comments, please leave them below.