state_of_the_nation 1.1.2 → 1.1.3

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
2
  SHA1:
3
- metadata.gz: 3cc3e890bee0ef29ba0095890cadf503ad9975b5
4
- data.tar.gz: 3ccae7dc38f6c533598f6fe3c89e755e4b5373a1
3
+ metadata.gz: 611580ac0c208f088555adadcd019dc5a6b424c0
4
+ data.tar.gz: f1d1819db563048a4b7a980dbe9db17b72989735
5
5
  SHA512:
6
- metadata.gz: 58bb0d7aacddcbcbf39d4eca1d0640b8639772846a76317c8608bf908c00b7cb5e51551b3004991f90e2316b321e83ad5067242e310f75207348c0c0965cfd3d
7
- data.tar.gz: acbf4ad6533efab8b16b74eb69bb036785f46e7b54269bc1278cc11a2affe17e8a3396863f6c02ec2b5ad9efbf9f729fa8b602c078eaeb15d28c3966c3bb4719
6
+ metadata.gz: 71c4a3084eeae10dae78e09c1139132671d3d5e5bafe47f4f72deaeac8ecbcb0543d6d10f80d77166ea47ea7ec74d1b275ebf44390f1639383da1c830cb6896e
7
+ data.tar.gz: aec17ea9744fa0e7dc764944f4084922a4d4e2bed263892273047077a277d21936c36dc4d397057e2bbf00dff8ad2f7a0e81610a25a6bcdaf606bb3ec9402c26
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in state_of_the_nation.gemspec
4
4
  gemspec
5
+
6
+ gem 'sqlite3', '~> 1.3.6'
data/README.md CHANGED
@@ -2,9 +2,11 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/intercom/state_of_the_nation.svg?branch=master)](https://travis-ci.org/intercom/state_of_the_nation)
4
4
 
5
- StateOfTheNation makes modeling state that changes over time easy with ActiveRecord, allowing you to query the active value at any point in time, as well as ensure that your records don't overlap at any point.
5
+ StateOfTheNation helps model data whose _active_ state changes over time. It provides out-of-the-box query methods to locate the record or records active at any moment. Optionally, it also enforces _uniquely_ active constraints at the application level – ensuring that only one record in a collection is active at once.
6
6
 
7
- Take for example modeling the history of elected officials in the United States Government where multiple Senators and only one President may be "active" for any point in time. Modeling this with StateOfTheNation is easy like so:
7
+ ## Example
8
+
9
+ Take elected officials in the US Government: multiple Senators are in office (i.e. active) at any point in time, but there's only one President.
8
10
 
9
11
  ```ruby
10
12
  class Country < ActiveRecord::Base
@@ -25,8 +27,6 @@ class Senator < ActiveRecord::Base
25
27
  belongs_to :country
26
28
  considered_active.from(:entered_office_at).until(:left_office_at)
27
29
  end
28
-
29
-
30
30
  ```
31
31
 
32
32
  With this collection of models we can easy record and query the list of elected officials at any point in time, and be confident that any new records that we create don't collide.
@@ -34,43 +34,42 @@ With this collection of models we can easy record and query the list of elected
34
34
  ```ruby
35
35
 
36
36
  usa = Country.create(name: "United States of America")
37
- obama = usa.presidents.create!(entered_office_at: Date.new(2009, 1, 20), left_office_at: nil)
38
-
39
- wyden = usa.senators.create!(entered_office_at: Date.new(1996, 2, 6), left_office_at: nil, name: "Ron Wyden")
40
- boxer = usa.senators.create!(entered_office_at: Date.new(1993, 1, 3), left_office_at: nil, name: "Barbara Boxer")
37
+ obama = usa.presidents.create!(name: "Barack Obama", entered_office_at: Date.new(2009, 1, 20))
41
38
 
42
- usa.active_president(Date.new(2015, 1, 1))
39
+ usa.senators.create!(name: "Ron Wyden", entered_office_at: Date.new(1996, 2, 6))
40
+ usa.senators.create!(name: "Barbara Boxer", entered_office_at: Date.new(1993, 1, 3))
41
+ usa.senators.create!(name: "Alan Cranston", entered_office_at: Date.new(1969, 1, 3), left_office_at: Date.new(1993, 1, 3))
43
42
 
44
- # => President(id: 1, name: "Barack Obama")
43
+ usa.active_president(Date.new(2015))
44
+ # => President(id: 1, name: "Barack Obama", …)
45
45
 
46
- usa.active_senators(Date.new(2015, 1, 1))
47
- # => [
48
- # Senator(id: 1, name: "Ron Wyden"),
49
- # Senator(id: 2, name: "Barbara Boxer")
50
- # ...
51
- # ]
46
+ obama.active?
47
+ #=> true
52
48
 
49
+ usa.active_senators(Date.new(2015))
50
+ # => [Senator(id: 1, name: "Ron Wyden", …), Senator(id: 2, name: "Barbara Boxer", …)]
53
51
 
52
+ usa.presidents.create!(name: "Mitt Romney", entered_office_at: Date.new(2013, 1, 20))
53
+ # => StateOfTheNation::ConflictError
54
54
  ```
55
+
55
56
  ## IdentityCache Support
56
57
 
57
- StateOfTheNation optionally supports fetching child records out of an IdentityCache cache instead of reading directly from the SQL table.
58
+ StateOfTheNation optionally supports fetching records through [IdentityCache](https://github.com/Shopify/identity_cache) instead of reading directly from the database.
58
59
 
59
- For example if the Country model uses IdentityCache to cache the has_many relationship to President, you can make StateOfTheNation use the IdentityCache methods by calling `.with_identity_cache` on your `has_active` or `has_uniquely_active` definitions like so.
60
+ For example if the `Country` model uses IdentityCache to cache the `has_many` relationship to `President`, you can instruct StateOfTheNation to fetch from the cache by calling `.with_identity_cache` on your `has_active` or `has_uniquely_active` definitions:
60
61
 
61
62
  ```ruby
62
63
  class Country
63
64
  include IdentityCache
64
65
  include StateOfTheNation
65
-
66
+
66
67
  has_many(:presidents)
67
68
  cache_has_many(:presidents)
68
69
  has_uniquely_active(:president).with_identity_cache
69
70
  end
70
71
  ```
71
72
 
72
- Now every time the `Country#active_president` method is called StateOfTheNation will read through the IdentityCache methods and avoid a SELECT operation if possible.
73
-
74
73
  ## Installation
75
74
 
76
75
  Add this line to your application's Gemfile:
@@ -96,4 +95,3 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
96
95
  ## Contributing
97
96
 
98
97
  Bug reports and pull requests are welcome on GitHub at https://github.com/intercom/state_of_the_nation. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org/) code of conduct.
99
-
@@ -1,4 +1,5 @@
1
- require "state_of_the_nation/errors"
1
+ require "state_of_the_nation/errors/conflict_error"
2
+ require "state_of_the_nation/errors/configuration_error"
2
3
  require "state_of_the_nation/version"
3
4
  require "state_of_the_nation/query_string"
4
5
  require "active_support/all"
@@ -105,13 +106,13 @@ module StateOfTheNation
105
106
 
106
107
  def prevent_active_collisions
107
108
  return unless prevent_multiple_active
108
- raise ConfigurationError.new if bad_configuration?
109
+ raise ConfigurationError if bad_configuration?
109
110
  return unless model.present?
110
111
 
111
- raise ConflictError.new if other_record_active_in_range?
112
+ raise ConflictError.new(self, other_records_active_in_range) if other_records_active_in_range.any?
112
113
  end
113
114
 
114
- def other_record_active_in_range?
115
+ def other_records_active_in_range
115
116
  records = self.class.where(parent_association => model)
116
117
  # all records scoped to the model (e.g. all subscriptions for a customer)
117
118
 
@@ -126,7 +127,7 @@ module StateOfTheNation
126
127
  # find competing records which *finish* being active AFTER this record *starts* being active
127
128
  # (or ones which are not set to finish being active)
128
129
 
129
- records.any?
130
+ records
130
131
  end
131
132
 
132
133
  def model
@@ -1,4 +1,3 @@
1
1
  module StateOfTheNation
2
2
  ConfigurationError = Class.new(StandardError)
3
- ConflictError = Class.new(StandardError)
4
3
  end
@@ -0,0 +1,16 @@
1
+ module StateOfTheNation
2
+ class ConflictError < StandardError
3
+ def initialize(record, conflicting_records)
4
+ super(<<-MSG.strip_heredoc)
5
+ Attempted to commit record
6
+
7
+ #{record.inspect}
8
+
9
+ But encountered a conflict with timestamps on the following records
10
+
11
+ #{conflicting_records.map { |record| "- #{record.inspect}" }.join("\n")}
12
+
13
+ MSG
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  module StateOfTheNation
2
- VERSION = "1.1.2"
2
+ VERSION = "1.1.3"
3
3
  end
@@ -24,14 +24,16 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_development_dependency "bundler"
26
26
  spec.add_development_dependency "database_cleaner"
27
- spec.add_development_dependency "mysql"
27
+ # spec.add_development_dependency "mysql"
28
28
  spec.add_development_dependency "pg"
29
+ spec.add_development_dependency "pry", "0.12.2"
30
+ spec.add_development_dependency "rb-readline"
29
31
  spec.add_development_dependency "rake", "~> 10.0"
30
32
  spec.add_development_dependency "rspec", "~> 3.0"
31
33
  spec.add_development_dependency "rspec-rails"
32
34
  spec.add_development_dependency "shoulda-matchers"
33
- spec.add_development_dependency "sqlite3"
35
+ spec.add_development_dependency "sqlite3", "1.4.0"
34
36
 
35
- spec.add_runtime_dependency "activesupport", ">= 4.0.0"
36
- spec.add_runtime_dependency "activerecord", ">= 4.0.0"
37
+ spec.add_runtime_dependency "activesupport", ">= 5.0.0"
38
+ spec.add_runtime_dependency "activerecord", ">= 5.0.0"
37
39
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: state_of_the_nation
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick O'Doherty
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2016-01-08 00:00:00.000000000 Z
12
+ date: 2019-03-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -40,7 +40,7 @@ dependencies:
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
42
  - !ruby/object:Gem::Dependency
43
- name: mysql
43
+ name: pg
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - ">="
@@ -54,7 +54,21 @@ dependencies:
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  - !ruby/object:Gem::Dependency
57
- name: pg
57
+ name: pry
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '='
61
+ - !ruby/object:Gem::Version
62
+ version: 0.12.2
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.12.2
70
+ - !ruby/object:Gem::Dependency
71
+ name: rb-readline
58
72
  requirement: !ruby/object:Gem::Requirement
59
73
  requirements:
60
74
  - - ">="
@@ -127,44 +141,44 @@ dependencies:
127
141
  name: sqlite3
128
142
  requirement: !ruby/object:Gem::Requirement
129
143
  requirements:
130
- - - ">="
144
+ - - '='
131
145
  - !ruby/object:Gem::Version
132
- version: '0'
146
+ version: 1.4.0
133
147
  type: :development
134
148
  prerelease: false
135
149
  version_requirements: !ruby/object:Gem::Requirement
136
150
  requirements:
137
- - - ">="
151
+ - - '='
138
152
  - !ruby/object:Gem::Version
139
- version: '0'
153
+ version: 1.4.0
140
154
  - !ruby/object:Gem::Dependency
141
155
  name: activesupport
142
156
  requirement: !ruby/object:Gem::Requirement
143
157
  requirements:
144
158
  - - ">="
145
159
  - !ruby/object:Gem::Version
146
- version: 4.0.0
160
+ version: 5.0.0
147
161
  type: :runtime
148
162
  prerelease: false
149
163
  version_requirements: !ruby/object:Gem::Requirement
150
164
  requirements:
151
165
  - - ">="
152
166
  - !ruby/object:Gem::Version
153
- version: 4.0.0
167
+ version: 5.0.0
154
168
  - !ruby/object:Gem::Dependency
155
169
  name: activerecord
156
170
  requirement: !ruby/object:Gem::Requirement
157
171
  requirements:
158
172
  - - ">="
159
173
  - !ruby/object:Gem::Version
160
- version: 4.0.0
174
+ version: 5.0.0
161
175
  type: :runtime
162
176
  prerelease: false
163
177
  version_requirements: !ruby/object:Gem::Requirement
164
178
  requirements:
165
179
  - - ">="
166
180
  - !ruby/object:Gem::Version
167
- version: 4.0.0
181
+ version: 5.0.0
168
182
  description: State of the Nation makes modeling object history easy.
169
183
  email:
170
184
  - patrick@intercom.io
@@ -183,7 +197,8 @@ files:
183
197
  - bin/console
184
198
  - bin/setup
185
199
  - lib/state_of_the_nation.rb
186
- - lib/state_of_the_nation/errors.rb
200
+ - lib/state_of_the_nation/errors/configuration_error.rb
201
+ - lib/state_of_the_nation/errors/conflict_error.rb
187
202
  - lib/state_of_the_nation/query_string.rb
188
203
  - lib/state_of_the_nation/version.rb
189
204
  - state_of_the_nation.gemspec
@@ -207,9 +222,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
222
  version: '0'
208
223
  requirements: []
209
224
  rubyforge_project:
210
- rubygems_version: 2.2.5
225
+ rubygems_version: 2.6.14.1
211
226
  signing_key:
212
227
  specification_version: 4
213
228
  summary: An easy way to model state that changes over time with ActiveRecord
214
229
  test_files: []
215
- has_rdoc: