DEV Community

loading...

Publishable Enum in Ruby on Rails with PostgreSQL

David Paluy
"Of course, I'm an optimist - I don't see much point in being anything else."
Originally published at majesticlabs.dev Updated on ・1 min read

Publishable/Unpublishable

There are many options to add publishing ability to your Rails model. The good reference is: https://naturaily.com/blog/ruby-on-rails-enum

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

This will create the PostgreSQL ENUM type.

Now it's time to add your 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.

I recommend defining the default value as the following:
add_column :articles, :status, :content_status, default: 'draft'

Also, if you need to make various queries to your model based on the status, add an index:
add_index :articles, :status

Add the publishing ability to your article:

class Article < ApplicationRecord
  include Publishable
end
Enter fullscreen mode Exit fullscreen mode

We are still missing all Rails scopes and other enum features.

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
Enter fullscreen mode Exit fullscreen mode

This adds all Rails scopes and magic. For example:

  • Operator.published
  • operator.published?
  • operator.published!

Happy Hacking!

Discussion (0)