affairs_of_state 0.1.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 82cee7ae333311fa7e78ad67e2dadf4519588278
4
- data.tar.gz: c9e55851f6777e1c0db00e04752b620537cfdf4f
2
+ SHA256:
3
+ metadata.gz: 2757335e832c9809fa86e7c365dda4d6fe31b49ab837665ecbd80ec2f3b27ac2
4
+ data.tar.gz: 18c9e1b16df324170b4af93859379540e56aafa27068490a743bd155b3a9c83a
5
5
  SHA512:
6
- metadata.gz: 9a6113b5f54561f269db052207e4cdc352495ff90af4919422b16704db46b9c3da3898f41dd8660b68dab77fc7db6be71d523f374bc81bbd7088522bcfc527d7
7
- data.tar.gz: 207c299cae44330886c9ba4a93dbbff7a1d1d15eb119d05ebbff8153957a56df780ea01ad855e77846a76e68cf7f05f9decc0ad4ad1e5479d172de4d3fe2bd4d
6
+ metadata.gz: 6e9b37707ae931a4a9231b4b453b075db2d0c1e16c4bddf1696f20adcf26bd5b23744e6f185602d50e036465d1cf060dd2b4951857d252d387a5c140b4a18029
7
+ data.tar.gz: 03c8db3940a2c167922048afecfa75d1ad4f28fcb386e16fc57bbbe6101c2f8416fece5ba12bba7af21407746149ec0252d46a7ce407b618b7db9af1f535ad7b
@@ -0,0 +1,25 @@
1
+ name: CI
2
+
3
+ on: [ push, pull_request ]
4
+
5
+ jobs:
6
+ test:
7
+ strategy:
8
+ fail-fast: false
9
+ matrix:
10
+ gemfile:
11
+ - "activerecord-6.0.gemfile"
12
+ - "activerecord-6.1.gemfile"
13
+ - "activerecord-latest.gemfile"
14
+ runs-on: ubuntu-latest
15
+ env:
16
+ BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: 3.0.2
22
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
23
+ - name: Run tests
24
+ run: |
25
+ bundle exec rspec --format doc
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Affairs of State
2
2
 
3
- [![Build Status](https://travis-ci.org/kmcphillips/affairs_of_state.png?branch=master)](https://travis-ci.org/kmcphillips/affairs_of_state)
3
+ ![Build Status](https://github.com/kmcphillips/affairs_of_state/actions/workflows/ci.yml/badge.svg)
4
4
 
5
- You have an Active Record model. It nees to have multiple states, but not complex rules. This gem gives you validation, easy check and change methods, and a single configuration line.
5
+ 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.
6
6
 
7
7
  ## Installation
8
8
 
@@ -12,13 +12,7 @@ Add this line to your application's Gemfile:
12
12
  gem 'affairs_of_state'
13
13
  ```
14
14
 
15
- And then execute:
16
-
17
- ```ruby
18
- $ bundle
19
- ```
20
-
21
- Or install it yourself as:
15
+ Or install it with:
22
16
 
23
17
  ```ruby
24
18
  $ gem install affairs_of_state
@@ -29,7 +23,7 @@ $ gem install affairs_of_state
29
23
  The gem assumes you have a string column named `status` on your model:
30
24
 
31
25
  ```ruby
32
- add_column :model_name, :status, :default => "active"
26
+ add_column :model_name, :status, default: "active"
33
27
  ```
34
28
 
35
29
  Then you just list your states in the model:
@@ -41,13 +35,13 @@ affairs_of_state :active, :inactive
41
35
  If you'd like to use another column, lets say `state`, pass it in as a configuration option:
42
36
 
43
37
  ```ruby
44
- affairs_of_state :active, :inactive, :column => :state
38
+ affairs_of_state :active, :inactive, column: :state
45
39
  ```
46
40
 
47
41
  You can also turn off validation:
48
42
 
49
43
  ```ruby
50
- affairs_of_state :active, :inactive, :allow_blank => true
44
+ affairs_of_state :active, :inactive, allow_blank: true
51
45
  ```
52
46
 
53
47
  Or give it a long list of statuses:
@@ -59,10 +53,14 @@ affairs_of_state :ordered, :cancelled, :shipped, :lost, :in_transit
59
53
  You can also pass a proc or a method name symbol to the :if option to bypass validation:
60
54
 
61
55
  ```ruby
62
- affairs_of_state :active, :inactive, :if => lambda{|object| only_validate_if_this_is_true(object) }
63
- # or
64
- affairs_of_state :active, :inactive, :if => :only_validate_if_this_method_returns_true
56
+ affairs_of_state :active, :inactive, if: ->(object) { only_validate_if_this_is_true(object) }
65
57
  ```
58
+ or
59
+ ```ruby
60
+ affairs_of_state :active, :inactive, if: :only_validate_if_this_method_returns_true
61
+ ```
62
+
63
+ Currently it is limited only be called once per model.
66
64
 
67
65
 
68
66
  ## Methods
@@ -114,6 +112,6 @@ rspec
114
112
 
115
113
  ## The usual
116
114
 
117
- Author: Kevin McPhillips - github@kevinmcphillips.ca
115
+ By Kevin McPhillips (github@kevinmcphillips.ca)
118
116
 
119
- License: [MIT](http://opensource.org/licenses/MIT)
117
+ [MIT License](http://opensource.org/licenses/MIT)
@@ -16,10 +16,12 @@ Gem::Specification.new do |gem|
16
16
  gem.require_paths = ["lib"]
17
17
  gem.version = AffairsOfState::VERSION
18
18
 
19
- gem.add_dependency "activerecord", "> 3.0"
19
+ gem.add_dependency "activerecord", ">= 6.0"
20
+ gem.add_dependency "activesupport", ">= 6.0"
20
21
 
21
- gem.add_development_dependency "rspec", "~> 3.0"
22
- gem.add_development_dependency "sqlite3"
22
+ gem.add_development_dependency "rspec"
23
+ gem.add_development_dependency "sqlite3", "~> 1.4.0"
23
24
  gem.add_development_dependency "pry"
25
+ gem.add_development_dependency "rake"
24
26
 
25
27
  end
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '..'
4
+
5
+ gem 'activerecord', '~> 6.0'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '..'
4
+
5
+ gem 'activerecord', '~> 6.1'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '..'
4
+
5
+ gem 'activerecord'
@@ -0,0 +1,16 @@
1
+ module AffairsOfState
2
+ class Config
3
+ attr_accessor :column, :allow_blank, :scopes, :if
4
+ attr_reader :statuses
5
+
6
+ def statuses=(val)
7
+ @statuses = val.flatten.map(&:to_s)
8
+
9
+ @statuses.each do |status|
10
+ raise ArgumentError.new("Affairs of State: '#{ status }' is not a valid status") if ["new"].include?(status)
11
+ end
12
+
13
+ @statuses
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  module AffairsOfState
2
- VERSION = "0.1.4"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -1,67 +1,65 @@
1
+ require "active_support"
2
+ require "active_support/concern"
3
+ require "active_record"
4
+
1
5
  require "affairs_of_state/version"
6
+ require "affairs_of_state/config"
2
7
 
3
8
  module AffairsOfState
9
+ extend ActiveSupport::Concern
4
10
 
5
- def self.included(base)
6
- base.extend ClassMethods
7
- end
11
+ class_methods do
12
+ def affairs_of_state(*statuses, column: :status, allow_blank: false, scopes: true, if: nil)
13
+ raise ArgumentError.new("Affairs of State: cannot be invoked multiple times on the same model") if @affairs_of_state_config
14
+
15
+ affairs_of_state_config.statuses = statuses
16
+ affairs_of_state_config.column = column
17
+ affairs_of_state_config.allow_blank = allow_blank
18
+ affairs_of_state_config.scopes = scopes
19
+ affairs_of_state_config.if = binding.local_variable_get(:if)
8
20
 
9
- module ClassMethods
10
- def affairs_of_state(*args)
11
- @_status_options = ({:column => :status, :allow_blank => false, :scopes => true, :if => nil}).merge(args.extract_options!)
12
- @_statuses = args.flatten.map(&:to_s)
21
+ const_set(:STATUSES, affairs_of_state_config.statuses)
22
+
23
+ affairs_of_state_config.statuses.each do |status|
24
+ define_method("#{ status }?") do
25
+ self.send(self.class.affairs_of_state_config.column) == status
26
+ end
13
27
 
14
- const_set("STATUSES", @_statuses)
28
+ define_method("#{ status }!") do
29
+ self.send("#{ self.class.affairs_of_state_config.column }=", status)
30
+ self.save
31
+ end
32
+ end
15
33
 
16
- validates(@_status_options[:column], :inclusion => {:in => @_statuses, :allow_blank => @_status_options[:allow_blank]}, :if => @_status_options[:if])
34
+ validates(affairs_of_state_config.column, inclusion: { in: affairs_of_state_config.statuses, allow_blank: affairs_of_state_config.allow_blank }, if: affairs_of_state_config.if)
17
35
 
18
- if @_status_options[:scopes]
19
- @_statuses.each do |status|
20
- raise "Affairs of State: '#{ status }' is not a valid status" unless valid_status?(status)
21
- self.scope status.to_sym, -> { where(@_status_options[:column] => status.to_s) }
36
+ if affairs_of_state_config.scopes
37
+ affairs_of_state_config.statuses.each do |status|
38
+ self.scope(status.to_sym, -> { where(affairs_of_state_config.column => status) })
22
39
  end
23
40
  end
24
41
 
25
42
  include InstanceMethods
26
43
  extend SingletonMethods
44
+
27
45
  true
28
46
  end
29
47
 
30
- private
31
-
32
- def valid_status?(status)
33
- ![:new].include?(status.to_sym)
48
+ def affairs_of_state_config
49
+ @affairs_of_state_config ||= AffairsOfState::Config.new
34
50
  end
35
51
  end
36
52
 
37
53
  module InstanceMethods
38
- def method_missing(method, *args)
39
- if self.class::STATUSES.map{|s| "#{s}?".to_sym }.include?(method)
40
- self.class.send(:define_method, method) do
41
- self.status == method.to_s.gsub(/\?$/, "")
42
- end
43
-
44
- send method
45
-
46
- elsif self.class::STATUSES.map{|s| "#{s}!".to_sym }.include?(method)
47
- self.class.send(:define_method, method) do
48
- self.send("#{self.class.instance_variable_get('@_status_options')[:column]}=", method.to_s.gsub(/\!$/, ""))
49
- self.save
50
- end
51
-
52
- send method
53
- else
54
- super
55
- end
56
- end
57
54
  end
58
55
 
59
56
  module SingletonMethods
60
57
  def statuses_for_select
61
- @_statuses.map{|s| [s.humanize, s]}
58
+ affairs_of_state_config.statuses.map{ |s| [s.humanize, s] }
62
59
  end
63
60
  end
64
-
65
61
  end
66
62
 
67
- ActiveRecord::Base.send :include, AffairsOfState
63
+ ActiveSupport.on_load(:active_record) do
64
+ ::ActiveRecord::Base.send :include, AffairsOfState
65
+ end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe AffairsOfState do
4
-
5
4
  describe "with a simple configuration" do
6
5
  class Pie < ActiveRecord::Base
7
6
  affairs_of_state :active, :inactive, :cancelled
@@ -71,6 +70,16 @@ describe AffairsOfState do
71
70
  it "should validate the column is set" do
72
71
  expect(Pie2.new(status: nil, super_status: "active")).to be_valid
73
72
  end
73
+
74
+ it "should know the accessors" do
75
+ expect(Pie2.new(status: nil, super_status: "inactive").inactive?).to be(true)
76
+ end
77
+
78
+ it "should know the setters" do
79
+ instance = Pie2.create!(status: nil, super_status: "inactive")
80
+ expect(instance.active!).to be(true)
81
+ expect(instance.super_status).to eq("active")
82
+ end
74
83
  end
75
84
 
76
85
  describe "without validations" do
@@ -163,8 +172,18 @@ describe AffairsOfState do
163
172
 
164
173
  describe "invalid status name" do
165
174
  it "should raise a good warning" do
166
- expect(->{ class Pie8 < ActiveRecord::Base ; affairs_of_state :new ; end }).to raise_error("Affairs of State: 'new' is not a valid status")
175
+ expect(->{ class Pie8 < ActiveRecord::Base ; affairs_of_state :new ; end }).to raise_error(ArgumentError, "Affairs of State: 'new' is not a valid status")
167
176
  end
168
177
  end
169
178
 
179
+ describe "multiple invocations" do
180
+ it "raises an error" do
181
+ expect(->{
182
+ class Pie9 < ActiveRecord::Base
183
+ affairs_of_state :not_important
184
+ affairs_of_state :something
185
+ end
186
+ }).to raise_error(ArgumentError, "Affairs of State: cannot be invoked multiple times on the same model")
187
+ end
188
+ end
170
189
  end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe AffairsOfState::Config do
4
+ subject{ AffairsOfState::Config.new }
5
+
6
+ describe "accessors" do
7
+ let(:expected){ double }
8
+
9
+ it "has :column" do
10
+ subject.column = expected
11
+ expect(subject.column).to eq(expected)
12
+ end
13
+
14
+ it "has :allow_blank" do
15
+ subject.allow_blank = expected
16
+ expect(subject.allow_blank).to eq(expected)
17
+ end
18
+
19
+ it "has :scopes" do
20
+ subject.scopes = expected
21
+ expect(subject.scopes).to eq(expected)
22
+ end
23
+
24
+ it "has :if" do
25
+ subject.if = expected
26
+ expect(subject.if).to eq(expected)
27
+ end
28
+ end
29
+
30
+ describe "#statuses=" do
31
+ it "converts to string" do
32
+ subject.statuses = [:a, :b]
33
+ expect(subject.statuses).to eq(["a", "b"])
34
+ end
35
+
36
+ it "flattens" do
37
+ subject.statuses = ["a", [:b]]
38
+ expect(subject.statuses).to eq(["a", "b"])
39
+ end
40
+
41
+ it "makes sure no invalid statuses are allowed" do
42
+ expect(->{
43
+ subject.statuses = [:new]
44
+ }).to raise_error(ArgumentError, "Affairs of State: 'new' is not a valid status")
45
+ end
46
+ end
47
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,18 +1,18 @@
1
- require 'active_record'
2
- require 'affairs_of_state'
3
- require 'pry'
1
+ require "affairs_of_state"
2
+
3
+ require "pry"
4
+ require "sqlite3"
4
5
 
5
6
  RSpec.configure do |config|
6
7
  config.run_all_when_everything_filtered = true
7
8
  end
8
9
 
9
-
10
10
  ## Create an AR model to test with
11
11
  I18n.enforce_available_locales = false
12
12
 
13
13
  ActiveRecord::Base.establish_connection(
14
- :adapter => "sqlite3",
15
- :database => "#{File.expand_path(File.join(File.dirname(__FILE__), '..'))}/spec/db/test.sqlite3"
14
+ adapter: "sqlite3",
15
+ database: "#{File.expand_path(File.join(File.dirname(__FILE__), '..'))}/spec/db/test.sqlite3"
16
16
  )
17
17
 
18
18
  ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS 'pies'")
metadata CHANGED
@@ -1,45 +1,73 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: affairs_of_state
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin McPhillips
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-06 00:00:00.000000000 Z
11
+ date: 2021-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '6.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '6.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sqlite3
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
59
  - - "~>"
32
60
  - !ruby/object:Gem::Version
33
- version: '3.0'
61
+ version: 1.4.0
34
62
  type: :development
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - "~>"
39
67
  - !ruby/object:Gem::Version
40
- version: '3.0'
68
+ version: 1.4.0
41
69
  - !ruby/object:Gem::Dependency
42
- name: sqlite3
70
+ name: pry
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - ">="
@@ -53,7 +81,7 @@ dependencies:
53
81
  - !ruby/object:Gem::Version
54
82
  version: '0'
55
83
  - !ruby/object:Gem::Dependency
56
- name: pry
84
+ name: rake
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - ">="
@@ -74,24 +102,29 @@ executables: []
74
102
  extensions: []
75
103
  extra_rdoc_files: []
76
104
  files:
105
+ - ".github/workflows/ci.yml"
77
106
  - ".gitignore"
78
107
  - ".rspec"
79
- - ".travis.yml"
80
108
  - Gemfile
81
109
  - LICENSE
82
110
  - README.md
83
111
  - Rakefile
84
112
  - affairs_of_state.gemspec
113
+ - gemfiles/activerecord-6.0.gemfile
114
+ - gemfiles/activerecord-6.1.gemfile
115
+ - gemfiles/activerecord-latest.gemfile
85
116
  - lib/affairs_of_state.rb
117
+ - lib/affairs_of_state/config.rb
86
118
  - lib/affairs_of_state/version.rb
87
119
  - spec/affairs_of_state_spec.rb
120
+ - spec/config_spec.rb
88
121
  - spec/db/.gitkeep
89
122
  - spec/spec_helper.rb
90
123
  homepage: http://github.com/kmcphillips/affairs_of_state
91
124
  licenses:
92
125
  - MIT
93
126
  metadata: {}
94
- post_install_message:
127
+ post_install_message:
95
128
  rdoc_options: []
96
129
  require_paths:
97
130
  - lib
@@ -106,14 +139,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
139
  - !ruby/object:Gem::Version
107
140
  version: '0'
108
141
  requirements: []
109
- rubyforge_project:
110
- rubygems_version: 2.2.2
111
- signing_key:
142
+ rubygems_version: 3.2.22
143
+ signing_key:
112
144
  specification_version: 4
113
145
  summary: You have an Active Record model. It nees to have multiple states, but not
114
146
  complex rules. This gem gives you validation, easy check and change methods, and
115
147
  a single configuration line.
116
- test_files:
117
- - spec/affairs_of_state_spec.rb
118
- - spec/db/.gitkeep
119
- - spec/spec_helper.rb
148
+ test_files: []
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - "1.9.3"
4
- - "2.0.0"
5
- - "2.1.0"
6
- script: bundle exec rspec