Adding Publishing Ability to Rails Models

There are many options to add publishing ability to your Rails model. Let’s assume we have an Article model and we want to make it publishable.

Add activerecord-postgres_enum to your Gemfile

gem 'activerecord-postgres_enum'

You need this solution if you want to use schema.rb.

Let’s create a Publishable module

app/models/concerns/publishable.rb

module Publishable
  extend ActiveSupport::Concern
  STATUSES = %w[draft reviewing published unpublished].freeze
end

Create PostgreSQL enum

rails g migration add_content_status_type

class AddContentStatusType < ActiveRecord::Migration[6.0]
  def change
    create_enum :content_status, Publishable::STATUSES
  end
end

This will create the PostgreSQL ENUM type.

Add status to Article model

rails g migration add_status_to_articles status:content_status

This will create a migration to add status to the Article model.

Define the default value: ruby add_column :articles, :status, :content_status, default: 'draft'

For better query performance, add an index: ruby add_index :articles, :status

Add the publishing ability to your article:

class Article < ApplicationRecord
  include Publishable
end

The updated version of Publishable concern

module Publishable
  extend ActiveSupport::Concern
  STATUSES = %w[draft reviewing published unpublished].freeze

  included do
    enum status: STATUSES.zip(STATUSES).to_h
  end
end

This adds all Rails scopes and magic. For example: - Article.published - article.published? - article.published!