0.02
No release in over a year
Quickly define model state predicates and scopes at the same time.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

~> 7.0
 Project Readme

action_state

ActionState provides a simple DSL for defining Rails model states allowing you to query the state as an ActiveRecord scope on the class and a predicate on the instance.

For example, the following state definition defines a class scope Article.published and an instance predicate article.published?.

class Article < ApplicationRecord
  state(:published) { where(published_at: ..Time.current) }
  ...
end

✨ Contributing ✨

If you’re interested in contributing to this project, you can book a pairing session with me and we can work through it together and I can hopefully share some context with you. Otherwise, please feel free top open a PR / issue / description. ❤️

Usage

ActionState supports a small subset of ActiveRecord queries for the predicate definition, and delegates the scope definition to ActiveRecord.

It's not meant to comprehensively support every possible ActiveRecord query; rather it supports a few features that tend to lend themselves well to predicate definitions.

where

The where method checks for inclusion in an Enumerable, coverage by a Range, and equality with other types of value.

Inclusion in an Enumerable

state(:crafter) { where(role: ["designer", "developer"]) }

Covered by a Range

state(:negative) { where(stars: 1..4 }
state(:indifferent) { where(stars: 5..6) }
state(:positive) { where(stars: 7..9) }

state(:recently_published) { where(published_at: 1.week.ago..) }

Equality

state(:featured) { where(featured: true) }

where.not

The counterpart to where is where.not which checks for exclusion from an Enumerable or Range, and inequality with other types of value.

state(:deleted) { where.not(deleted_at: nil) }

excluding

The excluding method excludes specific instances of a model.

state(:normal) { excluding(special_post) }

Passing arguments

States can also be defined to accept arguments.

state(:before) { |whenever| where(created_at: ..whenever) }
state(:after) { |whenever| where(created_at: whenever..) }

Composing states

You can chain query methods together to form more complex queries.

state(:can_edit) { where(role: "admin").where.not(disabled: true) }

You can also compose multiple states together.

state(:published) { where(published: true) }
state(:featured) { published.where(featured: true) }

Installation

Add this line to your application's Gemfile:

gem "action_state"

And then execute:

$ bundle

Or install it yourself as:

$ gem install action_state

Finally, include ActionState in your model class or ApplicationRecord:

class ApplicationRecord < ActiveRecord::Base
  include ActionState
  ...
end

License

The gem is available as open source under the terms of the MIT License.