assignable_values 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -64,6 +64,16 @@ You can populate a `<select>` tag with pairs of internal values and human labels
64
64
 
65
65
  form.collection_select :genre, form.object.assignable_genres, :to_s, :humanized
66
66
 
67
+ If you don't like to use your I18n dictionary for humanizations, you can also declare them directly in your model like this:
68
+
69
+ class Song < ActiveRecord::Base
70
+ assignable_values_for :genre do
71
+ { 'pop' => 'Pop music',
72
+ 'rock' => 'Rock music',
73
+ 'electronic' => 'Electronic music' }
74
+ end
75
+ end
76
+
67
77
 
68
78
  ### Defining default values
69
79
 
@@ -90,6 +100,20 @@ Defaults can be lambdas:
90
100
  The lambda will be evaluated in the context of the record instance.
91
101
 
92
102
 
103
+ ### Allowing blank values
104
+
105
+ By default, an attribute *must* be assigned an value. If the value of an attribute is blank, the attribute
106
+ will get a validation error.
107
+
108
+ If you would like to change this behavior and allow blank values to be valid, use the `:allow_blank` option:
109
+
110
+ class Song < ActiveRecord::Base
111
+ assignable_values_for :genre, :default => 'rock', :allow_blank => true do
112
+ ['pop', 'rock', 'electronic']
113
+ end
114
+ end
115
+
116
+
93
117
  ### Values are only validated when they change
94
118
 
95
119
  Values are only validated when they change. This is useful when the list of assignable values can change during runtime:
@@ -174,16 +198,18 @@ The list of assignable values is generated at runtime. Since the given block is
174
198
  end
175
199
 
176
200
 
177
- Obtaining assignable values from a delegate
178
- -------------------------------------------
201
+ Obtaining assignable values from another source
202
+ -----------------------------------------------
179
203
 
180
- The list of assignable values can be provided by a delegate. This is useful for authorization scenarios like [Consul](https://github.com/makandra/consul) or [CanCan](https://github.com/ryanb/cancan), where permissions are defined in a single class.
204
+ The list of assignable values can be provided by any object that is accessible from your model. This is useful for authorization scenarios like [Consul](https://github.com/makandra/consul) or [CanCan](https://github.com/ryanb/cancan), where permissions are defined in a single class.
181
205
 
182
- class Song < ActiveRecord::Base
206
+ You can define the source of assignable values by setting the `:through` option to a lambda:
207
+
208
+ class Story < ActiveRecord::Base
183
209
  assignable_values_for :state, :through => lambda { Power.current }
184
210
  end
185
211
 
186
- `Power.current` must now respond to a method `assignable_song_states` or `assignable_song_states(song)` which returns an `Enumerable` of state strings:
212
+ `Power.current` must now respond to a method `assignable_story_states` or `assignable_story_states(story)` which returns an `Enumerable` of state strings:
187
213
 
188
214
  class Power
189
215
 
@@ -193,7 +219,7 @@ The list of assignable values can be provided by a delegate. This is useful for
193
219
  @role = role
194
220
  end
195
221
 
196
- def assignable_song_states(song)
222
+ def assignable_story_states(story)
197
223
  states = ['draft', 'pending']
198
224
  states << 'accepted' if @role == :admin
199
225
  states
@@ -203,30 +229,64 @@ The list of assignable values can be provided by a delegate. This is useful for
203
229
 
204
230
  Listing and validating works the same with delegation:
205
231
 
206
- song = Song.new(:state => 'accepted')
232
+ story = Story.new(:state => 'accepted')
207
233
 
208
234
  Power.current = Power.new(:guest)
209
- song.assignable_states # => ['draft', 'pending']
210
- song.valid? # => false
235
+ story.assignable_states # => ['draft', 'pending']
236
+ story.valid? # => false
211
237
 
212
238
  Power.current = Power.new(:admin)
213
- song.assignable_states # => ['draft', 'pending', 'accepted']
214
- song.valid? # => true
239
+ story.assignable_states # => ['draft', 'pending', 'accepted']
240
+ story.valid? # => true
215
241
 
216
242
  Note that delegated validation is skipped when the delegate is `nil`. This way your model remains usable when there is no authorization context, like in batch processes or the console:
217
243
 
218
- song = Song.new(:state => 'foo')
244
+ story = Story.new(:state => 'foo')
219
245
  Power.current = nil
220
- song.valid? # => true
246
+ story.valid? # => true
247
+
248
+ Think of this as enabling an optional authorization layer on top of your model validations, which can be switched on or off depending on the current context.
221
249
 
222
250
  Instead of a lambda you can also use the `:through` option to name an instance method:
223
251
 
224
- class Song < ActiveRecord::Base
252
+ class Story < ActiveRecord::Base
225
253
  attr_accessor :power
226
254
  assignable_values_for :state, :through => :power
227
255
  end
228
256
 
229
257
 
258
+ ### Obtaining assignable values from a Consul power
259
+
260
+ A common use case for the `:through` option is when there is some globally accessible object that knows about permissions for the current request. In practice you will find that it requires some effort to make sure such an object is properly instantiated and accessible.
261
+
262
+ If you are using [Consul](https://github.com/makandra/consul), you will get a lot of this plumbing for free. Consul gives you a macro `current_power` to instantiate a so called "power", which describes what the current user may access:
263
+
264
+ class ApplicationController < ActionController::Base
265
+ include Consul::Controller
266
+
267
+ current_power do
268
+ Power.new(current_user)
269
+ end
270
+
271
+ end
272
+
273
+ The code above will provide you with a helper method `current_power` for your controller and views. Everywhere else, you can simply access it from `Power.current`.
274
+
275
+ You can now delegate validation of assignable values to the current power by saying:
276
+
277
+ class Story < ActiveRecord::Base
278
+ authorize_values_for :state
279
+ end
280
+
281
+ This is a shortcut for saying:
282
+
283
+ class Story < ActiveRecord::Base
284
+ assignable_values_for :state, :through => lambda { Power.current }
285
+ end
286
+
287
+ Head over to the [Consul README](https://github.com/makandra/consul) for details.
288
+
289
+
230
290
  Installation
231
291
  ------------
232
292
 
@@ -241,13 +301,13 @@ Development
241
301
  -----------
242
302
 
243
303
  - Fork the repository.
244
- - Push your changes with specs.
304
+ - Push your changes with specs. There is a Rails 3 test application in `spec/app_root` if you need to test integration with a live Rails app.
245
305
  - Send me a pull request.
246
306
 
247
- I'm very eager to keep this gem leightweight and on topic. If you're unsure whether a change would make it into the gem, [talk to me beforehand](henning.koch@makandra.de).
307
+ I'm very eager to keep this gem leightweight and on topic. If you're unsure whether a change would make it into the gem, [talk to me beforehand](mailto:henning.koch@makandra.de).
248
308
 
249
309
 
250
310
  Credits
251
311
  -------
252
312
 
253
- [Henning Koch](henning.koch@makandra.de) from [makandra](http://makandra.com/).
313
+ [Henning Koch](mailto:henning.koch@makandra.de) from [makandra](http://makandra.com/).
@@ -15,6 +15,8 @@ Gem::Specification.new do |s|
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
16
  s.require_paths = ["lib"]
17
17
 
18
+ s.add_dependency('activerecord')
19
+
18
20
  s.add_development_dependency('rails', '~>3.1')
19
21
  s.add_development_dependency('rspec', '~>2.8')
20
22
  s.add_development_dependency('rspec-rails', '~>2.8')
@@ -48,6 +48,10 @@ module AssignableValues
48
48
 
49
49
  private
50
50
 
51
+ def parse_values(values)
52
+ values.to_a
53
+ end
54
+
51
55
  def current_value(record)
52
56
  record.send(property)
53
57
  end
@@ -115,10 +119,11 @@ module AssignableValues
115
119
 
116
120
  def raw_assignable_values(record)
117
121
  if delegate?
118
- assignable_values_from_delegate(record)
122
+ values = assignable_values_from_delegate(record)
119
123
  else
120
- record.instance_eval(&@values)
121
- end.to_a
124
+ values = record.instance_eval(&@values)
125
+ end
126
+ parse_values(values)
122
127
  end
123
128
 
124
129
  def delegate(record)
@@ -10,13 +10,26 @@ module AssignableValues
10
10
 
11
11
  def humanize_string_value(value)
12
12
  if value.present?
13
- dictionary_key = "assignable_values.#{model.name.underscore}.#{property}.#{value}"
14
- I18n.t(dictionary_key, :default => value.humanize)
13
+ if @hardcoded_humanizations
14
+ @hardcoded_humanizations[value]
15
+ else
16
+ dictionary_key = "assignable_values.#{model.name.underscore}.#{property}.#{value}"
17
+ I18n.t(dictionary_key, :default => value.humanize)
18
+ end
15
19
  end
16
20
  end
17
21
 
18
22
  private
19
23
 
24
+ def parse_values(values)
25
+ if values.is_a?(Hash)
26
+ @hardcoded_humanizations = values
27
+ values = values.keys
28
+ else
29
+ super
30
+ end
31
+ end
32
+
20
33
  def define_humanized_method
21
34
  restriction = self
22
35
  enhance_model do
@@ -44,7 +57,6 @@ module AssignableValues
44
57
  record.send("#{property}_was")
45
58
  end
46
59
 
47
-
48
60
  end
49
61
  end
50
62
  end
@@ -1,3 +1,3 @@
1
1
  module AssignableValues
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -4,13 +4,11 @@ require 'ostruct'
4
4
  describe AssignableValues::ActiveRecord do
5
5
 
6
6
  def disposable_song_class(&block)
7
- @klass = Class.new(Song, &block)
8
- @klass.class_eval do
9
- def self.name
10
- 'Song'
11
- end
7
+ klass = Class.new(Song, &block)
8
+ def klass.name
9
+ 'Song'
12
10
  end
13
- @klass
11
+ klass
14
12
  end
15
13
 
16
14
  describe '.assignable_values' do
@@ -99,22 +97,22 @@ describe AssignableValues::ActiveRecord do
99
97
  it 'should validate that the association is allowed' do
100
98
  allowed_association = Artist.create!
101
99
  disallowed_association = Artist.create!
102
- @klass = disposable_song_class do
100
+ klass = disposable_song_class do
103
101
  assignable_values_for :artist do
104
102
  [allowed_association]
105
103
  end
106
104
  end
107
- @klass.new(:artist => allowed_association).should be_valid
108
- @klass.new(:artist => disallowed_association).should_not be_valid
105
+ klass.new(:artist => allowed_association).should be_valid
106
+ klass.new(:artist => disallowed_association).should_not be_valid
109
107
  end
110
108
 
111
109
  it 'should allow a nil association if the :allow_blank option is set' do
112
- @klass = disposable_song_class do
110
+ klass = disposable_song_class do
113
111
  assignable_values_for :artist, :allow_blank => true do
114
112
  []
115
113
  end
116
114
  end
117
- record = @klass.new
115
+ record = klass.new
118
116
  record.artist.should be_nil
119
117
  record.should be_valid
120
118
  end
@@ -122,9 +120,9 @@ describe AssignableValues::ActiveRecord do
122
120
  it 'should allow a previously saved association even if that association is no longer allowed' do
123
121
  allowed_association = Artist.create!
124
122
  disallowed_association = Artist.create!
125
- @klass = disposable_song_class
126
- record = @klass.create!(:artist => disallowed_association)
127
- @klass.class_eval do
123
+ klass = disposable_song_class
124
+ record = klass.create!(:artist => disallowed_association)
125
+ klass.class_eval do
128
126
  assignable_values_for :artist do
129
127
  [allowed_association]
130
128
  end
@@ -134,36 +132,36 @@ describe AssignableValues::ActiveRecord do
134
132
 
135
133
  it "should not load a previously saved association if the association's foreign key hasn't changed" do
136
134
  association = Artist.create!
137
- @klass = disposable_song_class do
135
+ klass = disposable_song_class do
138
136
  assignable_values_for :artist do
139
137
  [association] # This example doesn't care about what's assignable. We're only interested in behavior up to the validation.
140
138
  end
141
139
  end
142
- record = @klass.create!(:artist => association)
140
+ record = klass.create!(:artist => association)
143
141
  Artist.should_not_receive(:find_by_id)
144
142
  record.valid?
145
143
  end
146
144
 
147
145
  it 'should not fail or allow nil if a previously saved association no longer exists in the database' do
148
146
  allowed_association = Artist.create!
149
- disposable_song_class.class_eval do
147
+ klass = disposable_song_class do
150
148
  assignable_values_for :artist do
151
149
  [allowed_association]
152
150
  end
153
151
  end
154
- record = @klass.new
152
+ record = klass.new
155
153
  record.stub :artist_id_was => -1
156
154
  record.should_not be_valid
157
155
  end
158
156
 
159
157
  it 'should uncache a stale association before validating' do
160
- @klass = disposable_song_class do
158
+ klass = disposable_song_class do
161
159
  assignable_values_for :artist do
162
160
  [] # This example doesn't care about what's assignable. We're only interested in behavior up to the validation.
163
161
  end
164
162
  end
165
163
  association = Artist.create!
166
- record = @klass.new
164
+ record = klass.new
167
165
  record.stub(:artist => association, :artist_id => -1) # This is a stale association: The associated object's id doesn't match the foreign key. This can happen in Rails 2, not Rails 3.
168
166
  record.should_receive(:artist).ordered.and_return(association)
169
167
  record.should_receive(:artist).ordered.with(true).and_return(association)
@@ -171,13 +169,13 @@ describe AssignableValues::ActiveRecord do
171
169
  end
172
170
 
173
171
  it 'should not uncache a fresh association before validating' do
174
- @klass = disposable_song_class do
172
+ klass = disposable_song_class do
175
173
  assignable_values_for :artist do
176
174
  [] # This example doesn't care about what's assignable. We're only interested in behavior up to the validation.
177
175
  end
178
176
  end
179
177
  association = Artist.create!
180
- record = @klass.new
178
+ record = klass.new
181
179
  record.stub(:artist => association, :artist_id => association.id) # This is a fresh association: The associated object's id matches the foreign key.
182
180
  record.should_receive(:artist).with(no_args).and_return(association)
183
181
  record.valid?
@@ -188,35 +186,35 @@ describe AssignableValues::ActiveRecord do
188
186
  context 'when delegating using the :through option' do
189
187
 
190
188
  it 'should obtain allowed values from a method with the given name' do
191
- @klass = disposable_song_class do
189
+ klass = disposable_song_class do
192
190
  assignable_values_for :genre, :through => :delegate
193
191
  def delegate
194
192
  OpenStruct.new(:assignable_song_genres => %w[pop rock])
195
193
  end
196
194
  end
197
- @klass.new(:genre => 'pop').should be_valid
198
- @klass.new(:genre => 'disallowed value').should_not be_valid
195
+ klass.new(:genre => 'pop').should be_valid
196
+ klass.new(:genre => 'disallowed value').should_not be_valid
199
197
  end
200
198
 
201
199
  it 'should be able to delegate to a lambda, which is evaluated in the context of the record instance' do
202
- @klass = disposable_song_class do
200
+ klass = disposable_song_class do
203
201
  assignable_values_for :genre, :through => lambda { delegate }
204
202
  def delegate
205
203
  OpenStruct.new(:assignable_song_genres => %w[pop rock])
206
204
  end
207
205
  end
208
- @klass.new(:genre => 'pop').should be_valid
209
- @klass.new(:genre => 'disallowed value').should_not be_valid
206
+ klass.new(:genre => 'pop').should be_valid
207
+ klass.new(:genre => 'disallowed value').should_not be_valid
210
208
  end
211
209
 
212
210
  it 'should skip the validation if that method returns nil' do
213
- @klass = disposable_song_class do
211
+ klass = disposable_song_class do
214
212
  assignable_values_for :genre, :through => :delegate
215
213
  def delegate
216
214
  nil
217
215
  end
218
216
  end
219
- @klass.new(:genre => 'pop').should be_valid
217
+ klass.new(:genre => 'pop').should be_valid
220
218
  end
221
219
 
222
220
  end
@@ -224,25 +222,25 @@ describe AssignableValues::ActiveRecord do
224
222
  context 'with :default option' do
225
223
 
226
224
  it 'should allow to set a default' do
227
- @klass = disposable_song_class do
225
+ klass = disposable_song_class do
228
226
  assignable_values_for :genre, :default => 'pop' do
229
227
  %w[pop rock]
230
228
  end
231
229
  end
232
- @klass.new.genre.should == 'pop'
230
+ klass.new.genre.should == 'pop'
233
231
  end
234
232
 
235
233
  it 'should allow to set a default through a lambda' do
236
- @klass = disposable_song_class do
234
+ klass = disposable_song_class do
237
235
  assignable_values_for :genre, :default => lambda { 'pop' } do
238
236
  %w[pop rock]
239
237
  end
240
238
  end
241
- @klass.new.genre.should == 'pop'
239
+ klass.new.genre.should == 'pop'
242
240
  end
243
241
 
244
242
  it 'should evaluate a lambda default in the context of the record instance' do
245
- @klass = disposable_song_class do
243
+ klass = disposable_song_class do
246
244
  assignable_values_for :genre, :default => lambda { default_genre } do
247
245
  %w[pop rock]
248
246
  end
@@ -250,7 +248,7 @@ describe AssignableValues::ActiveRecord do
250
248
  'pop'
251
249
  end
252
250
  end
253
- @klass.new.genre.should == 'pop'
251
+ klass.new.genre.should == 'pop'
254
252
  end
255
253
 
256
254
  end
@@ -258,54 +256,25 @@ describe AssignableValues::ActiveRecord do
258
256
  context 'when generating methods to list assignable values' do
259
257
 
260
258
  it 'should generate an instance method returning a list of assignable values' do
261
- @klass = disposable_song_class do
259
+ klass = disposable_song_class do
262
260
  assignable_values_for :genre do
263
261
  %w[pop rock]
264
262
  end
265
263
  end
266
- @klass.new.assignable_genres.should == %w[pop rock]
267
- end
268
-
269
- it "should define a method #humanized on strings in that list, which return up the value's' translation" do
270
- @klass = disposable_song_class do
271
- assignable_values_for :genre do
272
- %w[pop rock]
273
- end
274
- end
275
- @klass.new.assignable_genres.collect(&:humanized).should == ['Pop music', 'Rock music']
276
- end
277
-
278
- it 'should use String#humanize as a default translation' do
279
- @klass = disposable_song_class do
280
- assignable_values_for :genre do
281
- %w[electronic]
282
- end
283
- end
284
- @klass.new.assignable_genres.collect(&:humanized).should == ['Electronic']
285
- end
286
-
287
- it 'should not define a method #humanized on values that are not strings' do
288
- @klass = disposable_song_class do
289
- assignable_values_for :year do
290
- [1999, 2000, 2001]
291
- end
292
- end
293
- years = @klass.new.assignable_years
294
- years.should == [1999, 2000, 2001]
295
- years.first.should_not respond_to(:humanized)
264
+ klass.new.assignable_genres.should == %w[pop rock]
296
265
  end
297
266
 
298
267
  it 'should call #to_a on the list of assignable values, allowing ranges and scopes to be passed as allowed value descriptors' do
299
- @klass = disposable_song_class do
268
+ klass = disposable_song_class do
300
269
  assignable_values_for :year do
301
270
  1999..2001
302
271
  end
303
272
  end
304
- @klass.new.assignable_years.should == [1999, 2000, 2001]
273
+ klass.new.assignable_years.should == [1999, 2000, 2001]
305
274
  end
306
275
 
307
276
  it 'should evaluate the value block in the context of the record instance' do
308
- @klass = disposable_song_class do
277
+ klass = disposable_song_class do
309
278
  assignable_values_for :genre do
310
279
  genres
311
280
  end
@@ -313,30 +282,72 @@ describe AssignableValues::ActiveRecord do
313
282
  %w[pop rock]
314
283
  end
315
284
  end
316
- @klass.new.assignable_genres.should == %w[pop rock]
285
+ klass.new.assignable_genres.should == %w[pop rock]
317
286
  end
318
287
 
319
288
  it 'should include a previously saved value, even if is no longer allowed' do
320
- @klass = disposable_song_class do
289
+ klass = disposable_song_class do
321
290
  assignable_values_for :genre do
322
291
  %w[pop rock]
323
292
  end
324
293
  end
325
- record = @klass.new(:genre => 'ballad')
294
+ record = klass.new(:genre => 'ballad')
326
295
  record.save!(:validate => false)
327
296
  record.assignable_genres.should =~ %w[pop rock ballad]
328
297
  end
329
298
 
299
+ context 'humanization' do
300
+
301
+ it "should define a method #humanized on strings in that list, which return up the value's' translation" do
302
+ klass = disposable_song_class do
303
+ assignable_values_for :genre do
304
+ %w[pop rock]
305
+ end
306
+ end
307
+ klass.new.assignable_genres.collect(&:humanized).should == ['Pop music', 'Rock music']
308
+ end
309
+
310
+ it 'should use String#humanize as a default translation' do
311
+ klass = disposable_song_class do
312
+ assignable_values_for :genre do
313
+ %w[electronic]
314
+ end
315
+ end
316
+ klass.new.assignable_genres.collect(&:humanized).should == ['Electronic']
317
+ end
318
+
319
+ it 'should not define a method #humanized on values that are not strings' do
320
+ klass = disposable_song_class do
321
+ assignable_values_for :year do
322
+ [1999, 2000, 2001]
323
+ end
324
+ end
325
+ years = klass.new.assignable_years
326
+ years.should == [1999, 2000, 2001]
327
+ years.first.should_not respond_to(:humanized)
328
+ end
329
+
330
+ it 'should allow to directly declare humanized values by passing a hash to assignable_values_for' do
331
+ klass = disposable_song_class do
332
+ assignable_values_for :genre do
333
+ { 'pop' => 'Pop music', 'rock' => 'Rock music' }
334
+ end
335
+ end
336
+ klass.new.assignable_genres.collect(&:humanized).should =~ ['Pop music', 'Rock music']
337
+ end
338
+
339
+ end
340
+
330
341
  context 'with :through option' do
331
342
 
332
343
  it 'should retrieve assignable values from the given method' do
333
- @klass = disposable_song_class do
344
+ klass = disposable_song_class do
334
345
  assignable_values_for :genre, :through => :delegate
335
346
  def delegate
336
347
  @delegate ||= 'delegate'
337
348
  end
338
349
  end
339
- record = @klass.new
350
+ record = klass.new
340
351
  record.delegate.should_receive(:assignable_song_genres).and_return %w[pop rock]
341
352
  record.assignable_genres.should == %w[pop rock]
342
353
  end
@@ -347,25 +358,25 @@ describe AssignableValues::ActiveRecord do
347
358
  record_received(record)
348
359
  %w[pop rock]
349
360
  end
350
- @klass = disposable_song_class do
361
+ klass = disposable_song_class do
351
362
  assignable_values_for :genre, :through => :delegate
352
363
  define_method :delegate do
353
364
  delegate
354
365
  end
355
366
  end
356
- record = @klass.new
367
+ record = klass.new
357
368
  delegate.should_receive(:record_received).with(record)
358
369
  record.assignable_genres.should == %w[pop rock]
359
370
  end
360
371
 
361
372
  it 'should raise an error if the given method returns nil' do
362
- @klass = disposable_song_class do
373
+ klass = disposable_song_class do
363
374
  assignable_values_for :genre, :through => :delegate
364
375
  def delegate
365
376
  nil
366
377
  end
367
378
  end
368
- expect { @klass.new.assignable_genres }.to raise_error(AssignableValues::DelegateUnavailable)
379
+ expect { klass.new.assignable_genres }.to raise_error(AssignableValues::DelegateUnavailable)
369
380
  end
370
381
 
371
382
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: assignable_values
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
8
  - 2
10
- version: 0.1.2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Henning Koch
@@ -15,12 +15,27 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-02-20 00:00:00 +01:00
18
+ date: 2012-06-15 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
+ type: :runtime
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ name: activerecord
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ type: :development
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
24
39
  none: false
25
40
  requirements:
26
41
  - - ~>
@@ -31,11 +46,11 @@ dependencies:
31
46
  - 1
32
47
  version: "3.1"
33
48
  name: rails
34
- version_requirements: *id001
35
- type: :development
49
+ version_requirements: *id002
36
50
  - !ruby/object:Gem::Dependency
51
+ type: :development
37
52
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
53
+ requirement: &id003 !ruby/object:Gem::Requirement
39
54
  none: false
40
55
  requirements:
41
56
  - - ~>
@@ -46,11 +61,11 @@ dependencies:
46
61
  - 8
47
62
  version: "2.8"
48
63
  name: rspec
49
- version_requirements: *id002
50
- type: :development
64
+ version_requirements: *id003
51
65
  - !ruby/object:Gem::Dependency
66
+ type: :development
52
67
  prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
68
+ requirement: &id004 !ruby/object:Gem::Requirement
54
69
  none: false
55
70
  requirements:
56
71
  - - ~>
@@ -61,11 +76,11 @@ dependencies:
61
76
  - 8
62
77
  version: "2.8"
63
78
  name: rspec-rails
64
- version_requirements: *id003
65
- type: :development
79
+ version_requirements: *id004
66
80
  - !ruby/object:Gem::Dependency
81
+ type: :development
67
82
  prerelease: false
68
- requirement: &id004 !ruby/object:Gem::Requirement
83
+ requirement: &id005 !ruby/object:Gem::Requirement
69
84
  none: false
70
85
  requirements:
71
86
  - - ">="
@@ -75,8 +90,7 @@ dependencies:
75
90
  - 0
76
91
  version: "0"
77
92
  name: sqlite3
78
- version_requirements: *id004
79
- type: :development
93
+ version_requirements: *id005
80
94
  description: Restrict the values assignable to ActiveRecord attributes or associations. Or enums on steroids.
81
95
  email: henning.koch@makandra.de
82
96
  executables: []
@@ -157,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
171
  requirements: []
158
172
 
159
173
  rubyforge_project:
160
- rubygems_version: 1.3.9.3
174
+ rubygems_version: 1.3.9.4
161
175
  signing_key:
162
176
  specification_version: 3
163
177
  summary: Restrict the values assignable to ActiveRecord attributes or associations. Or enums on steroids.