Skip to content

Instantly share code, notes, and snippets.

@zhangyuan
Created February 21, 2013 10:47
Show Gist options
  • Select an option

  • Save zhangyuan/5003871 to your computer and use it in GitHub Desktop.

Select an option

Save zhangyuan/5003871 to your computer and use it in GitHub Desktop.
Model extension with publishing status.

Concerns::Publishable is a module to extend model with publishing ability. Model should have column named of publishing_status .

module Concerns
  module Publishable
    PUBLISHING_STATUSES = %w(unapproved approved published deleted).freeze
    extend ActiveSupport::Concern

    included do
      PUBLISHING_STATUSES.each do |status|
        define_method "is_#{status}?" do
          self.publishing_status == status
        end
      end

      attr_accessible :published_as
      validates :published_as, inclusion: PUBLISHING_STATUSES

      scope :published_as, (Proc.new do |*statuses|
        where(publishing_status: fetch_publishing_status_ids(*statuses))
      end)
    end

    module ClassMethods 
      def fetch_publishing_status_ids(*args)
        args.map {|status| PUBLISHING_STATUSES.index(status.to_s)}
      end

      def fetch_publishing_statuses(*args)
        args.map {|status_id| PUBLISHING_STATUSES.at status_id.to_i}
      end

      def publishing_status_i18n_name(name)
        I18n.t("publishing_status.#{name}", default: name)
      end
    end

    def publishing_status_i18n_name
      self.class.publishing_status_i18n_name(published_as)  
    end

    def published_as=(name)
      status_id = self.class.fetch_publishing_status_ids(name).first
      write_attribute(:publishing_status, status_id)
    end

    def published_as
      self.class.fetch_publishing_statuses(read_attribute(:publishing_status)).first
    end
  end
end

An SimpleForm input for publishable model:

# Usage: f.input :published_as, as: :published_as

class PublishedAsInput < SimpleForm::Inputs::CollectionSelectInput
  def collection
    @collection ||= begin
      object.class::PUBLISHING_STATUSES.map do |name|
        [object.class.publishing_status_i18n_name(name), name]
      end
    end
  end

  def skip_include_blank?
    true
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment