Creating a drafts/approved publish queue in Rails

I wanted to allow any member of the public to submit new Videos for inclusion on a public-facing site - but I only wanted site Administrators to approve them for publishing. Here is the approach I took.

I protected the Videos using Devise authentication, so that users must first register/log in before submitting a video:

class VideosController < ApplicationController
  before_action :authenticate_user!, except: [:index, :show]

I added an Admin flag on the User model, so I could identify admin users. Within the Video's Create method, I set the appropriate flag on the Video status:

  def create
    @video = current_user.videos.build(video_params)
    if current_user.admin?
      # If the current user is an administrator, publish the video immediately
      @video.status = 'published'
    else
      # Otherwise, flag the video as a draft. It won't show on public pages until published
      @video.status = 'draft'
    end

Whenever videos are retrieved on the public-facing pages, I ensure that only published objects are returned, using where:{status: 'published'} - this includes within searches and when following tagged videos:

   def index
    if params[:query].present?
      @videos = Video.search(params[:query], where:{status: 'published'}
    elsif params[:tag].present?
      @tag = Tag.find_by(name: params[:tag])
      @videos = @tag.videos.where(status: 'published')
    elsif params[:sort].present?
      @videos = Video.where(status: 'published').order("#{params[:sort]} DESC")
    end
  end

From the admin panel, the Admin users can see a list of user-submitted videos, and can access a toggle to publish or reject them:

= simple_form_for(@video, html: { class: 'form' })  do |f|
  .form-group
    - if current_user.admin?
      %h4 Status
      .btn-group
        = f.collection_radio_buttons :status,
          [['published', 'published'] ,['draft', 'draft'],['rejected', 'rejected']],
          :first, :last,  :input_html => {style:'display:block', class: "radio"}

Publish/Reject panel

The end result is that users have the ability to input data into the database (helping to grow the site's content) but they don't have the ability to actually publish (helping to avoid spam and poor-quality content).

Back to articles

CONTACT