README.md
# SimplestStatus [![Gem Version](https://badge.fury.io/rb/simplest_status.svg)](http://badge.fury.io/rb/simplest_status) [![Code Climate](https://codeclimate.com/github/vigetlabs/simplest_status/badges/gpa.svg)](https://codeclimate.com/github/vigetlabs/simplest_status) [![Test Coverage](https://codeclimate.com/github/vigetlabs/simplest_status/badges/coverage.svg)](https://codeclimate.com/github/vigetlabs/simplest_status/coverage) [![Build Status](https://travis-ci.org/vigetlabs/simplest_status.svg)]((https://travis-ci.org/vigetlabs/simplest_status))
SimplestStatus is a gem built to provide simple, convenient status functionality for Rails models. It's designed to work with any currently-supported version of Rails (tested as far back as 3.0.0) and will work with Ruby 1.9.3 and up.
SimplestStatus is similar to the recently introduced [`enum`](http://api.rubyonrails.org/classes/ActiveRecord/Enum.html) (debuted in Rails 4.1), but is different in that it doesn't rely on a particular version of Rails and it also provides additional functionality like constant-based status lookup, label helpers, and validations.
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'simplest_status'
```
And then execute:
$ bundle
Or install it yourself as:
$ gem install simplest_status
## Usage
There are two ways to use SimplestStatus, through the default `statuses` method or the `simple_status` method.
The default assumes you've set up an `integer`-type `status` field with `:null => false` and `:default => 0`. For a `simple_status`, use the same column-type and settings, just give it the name of your custom status:
```ruby
class AddStatusToPostsMigration < ActiveRecord::Migration
def change
add_column :posts, :status, :integer, :null => false, :default => 0
add_column :posts, :locale, :integer, :null => false, :default => 0
end
end
```
Then in your model, extend `SimplestStatus` and list out your statuses using `statuses` or `simple_status`:
```ruby
class Post < ActiveRecord::Base
extend SimplestStatus
statuses :draft, :preview, :published, :archived
simple_status :locale, [:english, :spanish, :russian]
end
```
This will generate a number of constants, methods, and model validations.
#### Status List
```ruby
Post.statuses # => { :draft => 0, :preview => 1, :published => 2, :archived => 3 }
Post.locales # => { :english => 0, :spanish => 1, :russian => 2 }
```
The returned hash is a [`StatusCollection`](link) that, when iterated over, yields [`Status`](link) objects:
```
Post.statuses.first.tap do |status|
status.name # => :draft
status.value # => 0
status.string # => 'draft'
status.to_hash # => { :draft => 0 }
status.constant_name # => 'DRAFT'
status.label # => 'Draft'
status.for_select # => ['Draft', 0]
end
Post.locales.first.tap do |locale|
locale.name # => :english
locale.value # => 0
locale.string # => 'english'
locale.to_hash # => { :english => 0 }
locale.constant_name # => 'ENGLISH'
locale.label # => 'English'
locale.for_select # => ['English', 0]
end
```
It also provides a helper method for usage in a form select:
```ruby
Post.statuses.for_select # => [['Draft', 0], ['Preview', 1], ['Published', 2], ['Archived', 3]]
Post.locales.for_select # => [['English', 0], ['Spanish', 1], ['Russian', 2]]
```
#### Constants
Instead of referring to status values by the underlying integer, SimplestStatus generates constants for this purpose:
```ruby
Post::DRAFT # => 0
Post::PREVIEW # => 1
Post::PUBLISHED # => 2
Post::ARCHIVED # => 3
Post::ENGLISH # => 0
Post::SPANISH # => 1
Post::RUSSIAN # => 2
```
#### Scopes
```ruby
Post.draft
Post.preview
Post.published
Post.archived
Post.english
Post.spanish
Post.russian
```
#### Predicate Methods
```ruby
Post.new(:status => Post::DRAFT) do |post|
post.draft? # => true
post.preview? # => false
post.published? # => false
post.archived? # => false
end
Post.new(:locale => Post::RUSSIAN) do |post|
post.english? # => false
post.spanish? # => false
post.russian? # => true
end
```
#### Status Mutation Methods
```ruby
Post.new(:status => Post::ARCHIVED) do
post.draft # status from Post::ARCHIVED to Post::DRAFT
post.preview # status from Post::DRAFT to Post::PREVIEW
post.published # status from Post::PREVIEW to Post::PUBLISHED
post.archived # status from Post::PUBLISHED to Post::ARCHIVED
end
Post.new(:status => Post::SPANISH) do
post.english # locale from Post::SPANISH to Post::ENGLISH
post.spanish # locale from Post::ENGLISH to Post::SPANISH
post.russian # locale from Post::SPANISH to Post::RUSSIAN
end
```
#### Status Label Method
```ruby
Post.new(:status => Post::DRAFT).status_label # => 'Draft'
Post.new(:status => Post::PREVIEW).status_label # => 'Preview'
Post.new(:status => Post::PUBLISHED).status_label # => 'Published'
Post.new(:status => Post::ARCHIVED).status_label # => 'Archived'
Post.new(:locale => Post::ENGLISH).locale_label # => 'English'
Post.new(:locale => Post::SPANISH).locale_label # => 'Spanish'
Post.new(:locale => Post::RUSSIAN).locale_label # => 'Russian'
```
#### Status Validations
SimplestStatus will automatically add the following validations:
```ruby
validates :status, :presence => true, :inclusion => { :in => statuses.values }
validates :locale, :presence => true, :inclusion => { :in => locales.values }
```
***
<a href="http://code.viget.com">
<img src="http://code.viget.com/github-banner.png" alt="Code At Viget">
</a>
Visit [code.viget.com](http://code.viget.com) to see more projects from [Viget.](https://viget.com)