simplest_status 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +2 -2
- data/Appraisals +2 -2
- data/README.md +47 -6
- data/gemfiles/{rails_20.gemfile → rails_30.gemfile} +1 -1
- data/lib/simplest_status.rb +11 -5
- data/lib/simplest_status/model_methods.rb +57 -39
- data/lib/simplest_status/status_collection.rb +19 -3
- data/lib/simplest_status/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96f95a8993c3f7812338534148c8cf8c97754955
|
4
|
+
data.tar.gz: ae0f8f974872382df6b6ff331b31bf4cabf99f79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ffa1b67cf8a92c48bf6e2a8b1ed8c180e5d99687cf9352ba74df7bfa5a74b832672e6ca322226ea0df7689eb3ea58117b8e4e8f5d6530f4a28479fddc2b8856
|
7
|
+
data.tar.gz: 8d9cc09f264a0e1c6517afaa833bb0035005bb372ae726d956a524284241ea50ab727951b7defef78379eab3159eb00045508de64e4e68ec32dd9409127f9515
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -5,7 +5,7 @@ rvm:
|
|
5
5
|
- 2.1.0
|
6
6
|
- 2.2.2
|
7
7
|
gemfile:
|
8
|
-
- gemfiles/
|
8
|
+
- gemfiles/rails_30.gemfile
|
9
9
|
- gemfiles/rails_31.gemfile
|
10
10
|
- gemfiles/rails_32.gemfile
|
11
11
|
- gemfiles/rails_40.gemfile
|
@@ -14,7 +14,7 @@ gemfile:
|
|
14
14
|
matrix:
|
15
15
|
exclude:
|
16
16
|
- rvm: 2.2.2
|
17
|
-
gemfile: gemfiles/
|
17
|
+
gemfile: gemfiles/rails_30.gemfile
|
18
18
|
- rvm: 2.2.2
|
19
19
|
gemfile: gemfiles/rails_31.gemfile
|
20
20
|
- rvm: 2.2.2
|
data/Appraisals
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# SimplestStatus [](http://badge.fury.io/rb/simplest_status) [](https://codeclimate.com/github/vigetlabs/simplest_status) [](https://codeclimate.com/github/vigetlabs/simplest_status/coverage) []((https://travis-ci.org/vigetlabs/simplest_status))
|
2
2
|
|
3
|
-
SimplestStatus is a gem built to provide simple, convenient status functionality for Rails models. It's designed to work with
|
3
|
+
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.
|
4
4
|
|
5
|
-
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
|
5
|
+
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.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
Add this line to your application's Gemfile:
|
@@ -20,28 +20,33 @@ Or install it yourself as:
|
|
20
20
|
$ gem install simplest_status
|
21
21
|
|
22
22
|
## Usage
|
23
|
-
|
23
|
+
There are two ways to use SimplestStatus, through the default `statuses` method or the `simple_status` method.
|
24
|
+
|
25
|
+
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:
|
24
26
|
```ruby
|
25
27
|
class AddStatusToPostsMigration < ActiveRecord::Migration
|
26
28
|
def change
|
27
29
|
add_column :posts, :status, :integer, :null => false, :default => 0
|
30
|
+
add_column :posts, :locale, :integer, :null => false, :default => 0
|
28
31
|
end
|
29
32
|
end
|
30
33
|
```
|
31
|
-
Then in your model, extend `SimplestStatus` and list out your statuses
|
34
|
+
Then in your model, extend `SimplestStatus` and list out your statuses using `statuses` or `simple_status`:
|
32
35
|
```ruby
|
33
36
|
class Post < ActiveRecord::Base
|
34
37
|
extend SimplestStatus
|
35
38
|
|
36
39
|
statuses :draft, :preview, :published, :archived
|
40
|
+
|
41
|
+
simple_status :locale, [:english, :spanish, :russian]
|
37
42
|
end
|
38
43
|
```
|
39
|
-
|
40
44
|
This will generate a number of constants, methods, and model validations.
|
41
45
|
|
42
46
|
#### Status List
|
43
47
|
```ruby
|
44
48
|
Post.statuses # => { :draft => 0, :preview => 1, :published => 2, :archived => 3 }
|
49
|
+
Post.locales # => { :english => 0, :spanish => 1, :russian => 2 }
|
45
50
|
```
|
46
51
|
|
47
52
|
The returned hash is a [`StatusCollection`](link) that, when iterated over, yields [`Status`](link) objects:
|
@@ -55,11 +60,22 @@ Post.statuses.first.tap do |status|
|
|
55
60
|
status.label # => 'Draft'
|
56
61
|
status.for_select # => ['Draft', 0]
|
57
62
|
end
|
63
|
+
|
64
|
+
Post.locales.first.tap do |locale|
|
65
|
+
locale.name # => :english
|
66
|
+
locale.value # => 0
|
67
|
+
locale.string # => 'english'
|
68
|
+
locale.to_hash # => { :english => 0 }
|
69
|
+
locale.constant_name # => 'ENGLISH'
|
70
|
+
locale.label # => 'English'
|
71
|
+
locale.for_select # => ['English', 0]
|
72
|
+
end
|
58
73
|
```
|
59
74
|
|
60
75
|
It also provides a helper method for usage in a form select:
|
61
76
|
```ruby
|
62
77
|
Post.statuses.for_select # => [['Draft', 0], ['Preview', 1], ['Published', 2], ['Archived', 3]]
|
78
|
+
Post.locales.for_select # => [['English', 0], ['Spanish', 1], ['Russian', 2]]
|
63
79
|
```
|
64
80
|
|
65
81
|
#### Constants
|
@@ -69,6 +85,10 @@ Post::DRAFT # => 0
|
|
69
85
|
Post::PREVIEW # => 1
|
70
86
|
Post::PUBLISHED # => 2
|
71
87
|
Post::ARCHIVED # => 3
|
88
|
+
|
89
|
+
Post::ENGLISH # => 0
|
90
|
+
Post::SPANISH # => 1
|
91
|
+
Post::RUSSIAN # => 2
|
72
92
|
```
|
73
93
|
|
74
94
|
#### Scopes
|
@@ -77,6 +97,10 @@ Post.draft
|
|
77
97
|
Post.preview
|
78
98
|
Post.published
|
79
99
|
Post.archived
|
100
|
+
|
101
|
+
Post.english
|
102
|
+
Post.spanish
|
103
|
+
Post.russian
|
80
104
|
```
|
81
105
|
|
82
106
|
#### Predicate Methods
|
@@ -87,6 +111,12 @@ Post.new(:status => Post::DRAFT) do |post|
|
|
87
111
|
post.published? # => false
|
88
112
|
post.archived? # => false
|
89
113
|
end
|
114
|
+
|
115
|
+
Post.new(:locale => Post::RUSSIAN) do |post|
|
116
|
+
post.english? # => false
|
117
|
+
post.spanish? # => false
|
118
|
+
post.russian? # => true
|
119
|
+
end
|
90
120
|
```
|
91
121
|
|
92
122
|
#### Status Mutation Methods
|
@@ -97,6 +127,12 @@ Post.new(:status => Post::ARCHIVED) do
|
|
97
127
|
post.published # status from Post::PREVIEW to Post::PUBLISHED
|
98
128
|
post.archived # status from Post::PUBLISHED to Post::ARCHIVED
|
99
129
|
end
|
130
|
+
|
131
|
+
Post.new(:status => Post::SPANISH) do
|
132
|
+
post.english # locale from Post::SPANISH to Post::ENGLISH
|
133
|
+
post.spanish # locale from Post::ENGLISH to Post::SPANISH
|
134
|
+
post.russian # locale from Post::SPANISH to Post::RUSSIAN
|
135
|
+
end
|
100
136
|
```
|
101
137
|
|
102
138
|
#### Status Label Method
|
@@ -105,10 +141,15 @@ Post.new(:status => Post::DRAFT).status_label # => 'Draft'
|
|
105
141
|
Post.new(:status => Post::PREVIEW).status_label # => 'Preview'
|
106
142
|
Post.new(:status => Post::PUBLISHED).status_label # => 'Published'
|
107
143
|
Post.new(:status => Post::ARCHIVED).status_label # => 'Archived'
|
144
|
+
|
145
|
+
Post.new(:locale => Post::ENGLISH).locale_label # => 'English'
|
146
|
+
Post.new(:locale => Post::SPANISH).locale_label # => 'Spanish'
|
147
|
+
Post.new(:locale => Post::RUSSIAN).locale_label # => 'Russian'
|
108
148
|
```
|
109
149
|
|
110
150
|
#### Status Validations
|
111
151
|
SimplestStatus will automatically add the following validations:
|
112
152
|
```ruby
|
113
|
-
validates :status, :presence => true, :inclusion => { :in =>
|
153
|
+
validates :status, :presence => true, :inclusion => { :in => statuses.values }
|
154
|
+
validates :locale, :presence => true, :inclusion => { :in => locales.values }
|
114
155
|
```
|
data/lib/simplest_status.rb
CHANGED
@@ -5,12 +5,18 @@ module SimplestStatus
|
|
5
5
|
autoload :ModelMethods, 'simplest_status/model_methods'
|
6
6
|
|
7
7
|
def statuses(*status_list)
|
8
|
-
|
9
|
-
|
10
|
-
end
|
8
|
+
instance_variable_get(:@statuses) || simple_status(:status, status_list)
|
9
|
+
end
|
11
10
|
|
12
|
-
|
11
|
+
def simple_status(field_name, values)
|
12
|
+
status_collection_for(field_name, values).configure_for(self)
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
+
private
|
16
|
+
|
17
|
+
def status_collection_for(status_method, values)
|
18
|
+
values.reduce(StatusCollection.new(status_method)) do |collection, value|
|
19
|
+
collection.add(value)
|
20
|
+
end
|
15
21
|
end
|
16
22
|
end
|
@@ -1,61 +1,79 @@
|
|
1
1
|
module SimplestStatus
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
class ModelMethods
|
3
|
+
attr_reader :model, :statuses
|
4
|
+
|
5
|
+
def initialize(model, statuses)
|
6
|
+
@model = model
|
7
|
+
@statuses = statuses
|
5
8
|
end
|
6
9
|
|
7
|
-
|
10
|
+
def add
|
11
|
+
define_statuses_accessor_for statuses
|
8
12
|
|
9
|
-
|
10
|
-
def configure
|
11
|
-
model.statuses.each do |status|
|
12
|
-
set_constant_for status
|
13
|
-
define_class_methods_for status
|
14
|
-
define_instance_methods_for status
|
15
|
-
end
|
13
|
+
populate_statuses
|
16
14
|
|
17
|
-
|
18
|
-
set_validations
|
19
|
-
end
|
15
|
+
process_each_status
|
20
16
|
|
21
|
-
|
17
|
+
define_status_label_method_for statuses
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
19
|
+
set_validations_for statuses
|
20
|
+
end
|
26
21
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
private
|
23
|
+
|
24
|
+
def define_statuses_accessor_for(statuses)
|
25
|
+
model.send :define_singleton_method, statuses.model_accessor do
|
26
|
+
instance_variable_get('@' + statuses.model_accessor)
|
31
27
|
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def populate_statuses
|
31
|
+
model.send(:instance_variable_set, '@' + statuses.model_accessor, statuses)
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
def process_each_status
|
35
|
+
statuses.each do |status|
|
36
|
+
set_constant_for status
|
37
|
+
define_class_methods_for status, statuses.status_name
|
38
|
+
define_instance_methods_for status
|
36
39
|
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_constant_for(status)
|
43
|
+
model.send :const_set, status.constant_name, status.value
|
44
|
+
end
|
37
45
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
46
|
+
def define_class_methods_for(status, status_name)
|
47
|
+
model.send :define_singleton_method, status.symbol do
|
48
|
+
where(status_name => status.value)
|
42
49
|
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def define_instance_methods_for(status)
|
53
|
+
define_predicate(status, statuses.status_name)
|
54
|
+
define_status_setter(status, statuses.status_name)
|
55
|
+
end
|
43
56
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
57
|
+
def define_predicate(status, status_name)
|
58
|
+
model.send :define_method, "#{status.symbol}?" do
|
59
|
+
send(status_name) == status.value
|
48
60
|
end
|
61
|
+
end
|
49
62
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
63
|
+
def define_status_setter(status, status_name)
|
64
|
+
model.send :define_method, status.symbol do
|
65
|
+
update_attributes(status_name => status.value)
|
54
66
|
end
|
67
|
+
end
|
55
68
|
|
56
|
-
|
57
|
-
|
69
|
+
def define_status_label_method_for(statuses)
|
70
|
+
model.send :define_method, "#{statuses.status_name}_label" do
|
71
|
+
self.class.send(statuses.model_accessor).label_for send(statuses.status_name)
|
58
72
|
end
|
59
73
|
end
|
74
|
+
|
75
|
+
def set_validations_for(statuses)
|
76
|
+
model.send :validates, statuses.status_name, :presence => true, :inclusion => { :in => statuses.values }
|
77
|
+
end
|
60
78
|
end
|
61
79
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "active_support/inflector"
|
2
|
+
|
1
3
|
module SimplestStatus
|
2
4
|
autoload :Status, 'simplest_status/status'
|
3
5
|
|
@@ -14,9 +16,7 @@ module SimplestStatus
|
|
14
16
|
alias :value_for :[]
|
15
17
|
|
16
18
|
def status_for(input)
|
17
|
-
find
|
18
|
-
status.matches? input
|
19
|
-
end
|
19
|
+
find { |status| status.matches?(input) } || NullStatus.new
|
20
20
|
end
|
21
21
|
|
22
22
|
def add(status, value = self.size)
|
@@ -30,5 +30,21 @@ module SimplestStatus
|
|
30
30
|
def for_select
|
31
31
|
map(&:for_select)
|
32
32
|
end
|
33
|
+
|
34
|
+
def configure_for(model)
|
35
|
+
tap { ModelMethods.new(model, self).add }
|
36
|
+
end
|
37
|
+
|
38
|
+
def status_name
|
39
|
+
default
|
40
|
+
end
|
41
|
+
|
42
|
+
def model_accessor
|
43
|
+
status_name.to_s.pluralize
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
NullStatus = Struct.new(:value)
|
33
49
|
end
|
34
50
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simplest_status
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Stenberg
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -126,7 +126,7 @@ files:
|
|
126
126
|
- Rakefile
|
127
127
|
- bin/console
|
128
128
|
- bin/setup
|
129
|
-
- gemfiles/
|
129
|
+
- gemfiles/rails_30.gemfile
|
130
130
|
- gemfiles/rails_31.gemfile
|
131
131
|
- gemfiles/rails_32.gemfile
|
132
132
|
- gemfiles/rails_40.gemfile
|