Affairs of State

Build Status

You have an Active Record model. It nees to have multiple states, boolean convenience methods, simple validation, but not complex rules. This gem gives you this in a single line class method.

Installation

Add this line to your application's Gemfile:

gem 'affairs_of_state'

Or install it with:

$ gem install affairs_of_state

Usage

The gem assumes you have a string column named status on your model:

add_column :model_name, :status, default: "active"

Then you just list your states in the model:

affairs_of_state :active, :inactive

If you'd like to use another column, lets say state, pass it in as a configuration option:

affairs_of_state :active, :inactive, column: :state

You can scope the helper and scope methods by a prefix:

affairs_of_state :active, :inactive, prefix: :admin

You can also turn off validation:

affairs_of_state :active, :inactive, allow_blank: true

Or give it a long list of statuses:

affairs_of_state :ordered, :cancelled, :shipped, :lost, :in_transit

You can also pass a proc or a method name symbol to the :if option to bypass validation:

affairs_of_state :active, :inactive, if: ->(object) { only_validate_if_this_is_true(object) }

or

affairs_of_state :active, :inactive, if: :only_validate_if_this_method_returns_true

It can be called multiple times per model, provided as each time is with a different column, and that none of the statuses overlap. If either of these are not true it will raise on load.

Methods

The gem provides methods for checking and setting your status. The question mark method returns a boolean, and the bang method changes to that status. Lets assume you have "active" and "cancelled" as defined status:

widget = Widget.first
widget.cancelled! if widget.active?

These methods are scoped by the prefix if one is set:

widget = Widget.first
widget.admin_cancelled! if widget.admin_active?

You can also access all your statuses on the model. If only one is defined it is default, otherwise the column name needs to be passed in:

Widget.statuses  # -> ["active", "cancelled"]
Widget.statuses(:status)  # -> ["active", "cancelled"]

It also provides scopes automagically, scoped by prefix if one is set:

Widget.active
Widget.cancelled
Widget.admin_active
Widget.admin_cancelled

For select inputs in forms there is a convenience method that returns all states in the format expected by options_for_select. Again if only one is defined on the model it returns as default, if multiple are defined the column name needs to be passed in:

<%= f.select :status, options_for_select(Widget.statuses_for_select) %>
<%= f.select :status, options_for_select(Widget.statuses_for_select(:status)) %>

"But I want callbacks and validations etc."

Then this gem isn't for you. Consider:

https://github.com/rubyist/aasm

https://github.com/pluginaweek/state_machine

Tests

Just run rspec:

rspec

The usual

By Kevin McPhillips ([email protected])

MIT License