ampere 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/ampere.gemspec +2 -2
- data/lib/ampere/model.rb +3 -3
- data/spec/models/indices_spec.rb +36 -35
- data/spec/models/model_spec.rb +38 -38
- data/spec/models/queries_spec.rb +15 -15
- data/spec/models/relationships/belongs_to_spec.rb +46 -46
- data/spec/models/relationships/has_many_spec.rb +34 -29
- data/spec/models/relationships/has_one_spec.rb +31 -30
- data/spec/models/timestamps_spec.rb +12 -12
- data/spec/models/updates_spec.rb +9 -9
- data/spec/models/validations_spec.rb +6 -7
- data/spec/module/collections_ennumerable_spec.rb +15 -15
- data/spec/module/collections_spec.rb +14 -14
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.3
|
data/ampere.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "ampere"
|
8
|
-
s.version = "1.2.
|
8
|
+
s.version = "1.2.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Max Thom Stahl"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-10-02"
|
13
13
|
s.description = "An ActiveRecord/Mongoid-esque object model for the Redis key/value data store."
|
14
14
|
s.email = "max@villainousindustri.es"
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/ampere/model.rb
CHANGED
@@ -315,7 +315,7 @@ module Ampere
|
|
315
315
|
# Set attr with key where referred model is stored
|
316
316
|
self.send("#{field_name}_id=", val.id)
|
317
317
|
# Also update that model's hash with a pointer back to here
|
318
|
-
val.send("#{my_klass_name}_id=", self.send("id"))
|
318
|
+
val.send("#{my_klass_name}_id=", self.send("id")) if val.respond_to?("#{my_klass_name}_id=")
|
319
319
|
end
|
320
320
|
end
|
321
321
|
|
@@ -325,7 +325,7 @@ module Ampere
|
|
325
325
|
my_klass_name = to_s.downcase
|
326
326
|
|
327
327
|
define_method(:"#{field_name}") do
|
328
|
-
(Ampere.connection.smembers(key_for_has_many(
|
328
|
+
(Ampere.connection.smembers(key_for_has_many(my_klass_name, self.id, field_name))).map do |id|
|
329
329
|
eval(klass_name.to_s.capitalize).find(id)
|
330
330
|
end
|
331
331
|
end
|
@@ -333,7 +333,7 @@ module Ampere
|
|
333
333
|
define_method(:"#{field_name}=") do |val|
|
334
334
|
val.each do |v|
|
335
335
|
Ampere.connection.multi do
|
336
|
-
Ampere.connection.sadd(key_for_has_many(
|
336
|
+
Ampere.connection.sadd(key_for_has_many(my_klass_name, self.id, field_name), v.id)
|
337
337
|
# Set pointer for belongs_to
|
338
338
|
Ampere.connection.hset(key_for_find(v.class, v.id), "#{my_klass_name}_id", self.send("id"))
|
339
339
|
end
|
data/spec/models/indices_spec.rb
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "..", "spec_helper.rb")
|
2
2
|
|
3
3
|
describe "Model indices", :indices => true do
|
4
|
+
|
5
|
+
class Student
|
6
|
+
include Ampere::Model
|
7
|
+
|
8
|
+
field :first_name
|
9
|
+
field :last_name
|
10
|
+
field :student_id_num
|
11
|
+
|
12
|
+
index :last_name
|
13
|
+
index :student_id_num, :unique => true
|
14
|
+
end
|
15
|
+
|
4
16
|
before :each do
|
5
17
|
Redis.new.flushall
|
6
18
|
Ampere.connect
|
7
|
-
|
8
|
-
class Student
|
9
|
-
include Ampere::Model
|
10
|
-
|
11
|
-
field :first_name
|
12
|
-
field :last_name
|
13
|
-
field :student_id_num
|
14
|
-
|
15
|
-
index :last_name
|
16
|
-
index :student_id_num, :unique => true
|
17
|
-
end
|
18
|
-
|
19
|
+
|
19
20
|
@a = Student.create :first_name => "Hannibal",
|
20
21
|
:last_name => "Smith",
|
21
22
|
:student_id_num => "1001"
|
@@ -26,56 +27,56 @@ describe "Model indices", :indices => true do
|
|
26
27
|
:last_name => "Goldstein",
|
27
28
|
:student_id_num => "1003"
|
28
29
|
end
|
29
|
-
|
30
|
+
|
30
31
|
###
|
31
|
-
|
32
|
+
|
32
33
|
it 'should know about its own indices' do
|
33
34
|
Student.indices.should include(:last_name)
|
34
35
|
Student.indices.should_not include(:first_name)
|
35
36
|
Student.indices.should include(:student_id_num)
|
36
37
|
end
|
37
|
-
|
38
|
+
|
38
39
|
it 'should find an array of values for a non-unique index' do
|
39
40
|
smiths = Student.where(:last_name => "Smith")
|
40
41
|
smiths.should_not be_empty
|
41
42
|
smiths.to_a.map(&:first_name).should include("Hannibal")
|
42
43
|
smiths.to_a.map(&:first_name).should include("Cindy")
|
43
44
|
end
|
44
|
-
|
45
|
+
|
45
46
|
it 'should find a single value for a unique index' do
|
46
47
|
emmanuel = Student.where(:student_id_num => "1003")
|
47
48
|
emmanuel.should_not be_empty
|
48
49
|
emmanuel.first.first_name.should == "Emmanuel"
|
49
50
|
end
|
50
|
-
|
51
|
+
|
51
52
|
it 'should refuse to create an index on a field that does not exist' do
|
52
53
|
(->{
|
53
|
-
class
|
54
|
+
class Student1
|
54
55
|
include Ampere::Model
|
55
|
-
|
56
|
+
|
56
57
|
field :this_field_exists
|
57
58
|
|
58
59
|
index :this_field_exists
|
59
60
|
end
|
60
61
|
}).should_not raise_error
|
61
62
|
(->{
|
62
|
-
class
|
63
|
+
class Student2
|
63
64
|
include Ampere::Model
|
64
|
-
|
65
|
+
|
65
66
|
index :this_field_does_not_exist
|
66
67
|
end
|
67
68
|
}).should raise_error
|
68
69
|
(->{
|
69
|
-
class
|
70
|
+
class Student3
|
70
71
|
include Ampere::Model
|
71
|
-
|
72
|
+
|
72
73
|
field :this_field_exists
|
73
|
-
|
74
|
+
|
74
75
|
index [:this_field_exists, :but_this_one_does_not]
|
75
76
|
end
|
76
77
|
}).should raise_error
|
77
78
|
end
|
78
|
-
|
79
|
+
|
79
80
|
it 'should enforce the uniqueness of unique single-field indices' do
|
80
81
|
# The student_id_num field of Student is unique. If two Students
|
81
82
|
# with the same student_id_num are stored, the second should not
|
@@ -92,23 +93,23 @@ describe "Model indices", :indices => true do
|
|
92
93
|
}).should raise_error
|
93
94
|
Student.where(:student_id_num => "2000").first.first_name.should == "Bobby"
|
94
95
|
end
|
95
|
-
|
96
|
+
|
96
97
|
context 'compound indices' do
|
97
98
|
before :all do
|
98
99
|
class Professor
|
99
100
|
include Ampere::Model
|
100
|
-
|
101
|
+
|
101
102
|
field :first_name
|
102
103
|
field :last_name
|
103
104
|
field :employee_id_number
|
104
|
-
|
105
|
+
|
105
106
|
index :employee_id_number
|
106
107
|
index [:last_name, :first_name]
|
107
108
|
end
|
108
109
|
end
|
109
|
-
|
110
|
+
|
110
111
|
###
|
111
|
-
|
112
|
+
|
112
113
|
it 'should define compound indices' do
|
113
114
|
Professor.indices.should include([:first_name, :last_name])
|
114
115
|
|
@@ -119,7 +120,7 @@ describe "Model indices", :indices => true do
|
|
119
120
|
Professor.count.should == 1
|
120
121
|
Ampere.connection.exists("ampere.index.professor.first_name:last_name").should be_true
|
121
122
|
end
|
122
|
-
|
123
|
+
|
123
124
|
it 'should be able to search on both fields of a compound index' do
|
124
125
|
Professor.create :first_name => "Ava",
|
125
126
|
:last_name => "Jenkins",
|
@@ -135,16 +136,16 @@ describe "Model indices", :indices => true do
|
|
135
136
|
brandi.count.should == 1
|
136
137
|
brandi.first.employee_id_number.should == "31415929"
|
137
138
|
end
|
138
|
-
|
139
|
+
|
139
140
|
# it 'should still be able to search on just one field of a compound index' do
|
140
141
|
# pending
|
141
142
|
# end
|
142
143
|
end
|
143
|
-
|
144
|
+
|
144
145
|
###
|
145
|
-
|
146
|
+
|
146
147
|
after :all do
|
147
148
|
Redis.new.flushall
|
148
149
|
Ampere.disconnect
|
149
150
|
end
|
150
|
-
end
|
151
|
+
end
|
data/spec/models/model_spec.rb
CHANGED
@@ -4,22 +4,22 @@ describe "Base models", :model => true do
|
|
4
4
|
context "by themselves" do
|
5
5
|
class Post
|
6
6
|
include Ampere::Model
|
7
|
-
|
7
|
+
|
8
8
|
field :title
|
9
9
|
field :byline
|
10
10
|
field :content
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
before :all do
|
14
14
|
Ampere.connect
|
15
|
-
|
15
|
+
|
16
16
|
# Clear out Redis
|
17
17
|
Redis.new.flushall
|
18
|
-
|
18
|
+
|
19
19
|
# Define a model class here.
|
20
|
-
|
20
|
+
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# # #
|
24
24
|
|
25
25
|
context 'fields' do
|
@@ -32,46 +32,46 @@ describe "Base models", :model => true do
|
|
32
32
|
post.should respond_to(:content)
|
33
33
|
post.should respond_to(:"content=")
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
it "should know about its own fields" do
|
37
37
|
Post.fields.should include(:title)
|
38
38
|
Post.fields.should include(:byline)
|
39
39
|
Post.fields.should include(:content)
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
it "should have default values definable" do
|
43
43
|
class Comment
|
44
44
|
include Ampere::Model
|
45
|
-
|
45
|
+
|
46
46
|
field :subject, :default => "No subject"
|
47
47
|
field :content
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
comment = Comment.new
|
51
51
|
comment.subject.should == "No subject"
|
52
52
|
comment.content.should be_nil
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
it "should raise an exception when you try to set a field that doesn't exist" do
|
56
56
|
(->{Post.new :shazbot => "This isn't the right key"}).should raise_error
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
context 'types', :types => true do
|
60
60
|
before :all do
|
61
61
|
# Just adding a field with a type to Post
|
62
62
|
class Post
|
63
63
|
include Ampere::Model
|
64
|
-
|
64
|
+
|
65
65
|
field :pageviews, :type => Integer, :default => 0
|
66
66
|
end
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
it "should set field types for fields that have a type" do
|
70
70
|
Post.field_types.should_not be_nil
|
71
71
|
Post.field_types[:pageviews].should_not be_nil
|
72
72
|
Post.field_types[:pageviews].should == 'Integer'
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
it "shouldn't care what the value types are assigned to a field with no type defined" do
|
76
76
|
# Assign an int to the :title of a Post.
|
77
77
|
(->{
|
@@ -79,10 +79,10 @@ describe "Base models", :model => true do
|
|
79
79
|
:byline => "",
|
80
80
|
:content => "",
|
81
81
|
:pageviews => 1234
|
82
|
-
|
83
|
-
|
82
|
+
|
83
|
+
|
84
84
|
}).should_not raise_error
|
85
|
-
|
85
|
+
|
86
86
|
# Assign a string to the :title of a Post.
|
87
87
|
(->{
|
88
88
|
Post.create :title => "1234",
|
@@ -91,20 +91,20 @@ describe "Base models", :model => true do
|
|
91
91
|
:pageviews => 1234
|
92
92
|
}).should_not raise_error
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
it "should, given a field's type, only accept values for that field of that type" do
|
96
96
|
post = Post.create :title => "",
|
97
97
|
:byline => "",
|
98
98
|
:content => "",
|
99
99
|
:pageviews => 1234
|
100
|
-
|
100
|
+
|
101
101
|
# Try to assign a string to :year, raising an error.
|
102
102
|
(->{post.pageviews = "this is not an integer"}).should raise_error
|
103
103
|
(->{post.pageviews = 4321}).should_not raise_error
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
it "should have a 'new' method that works like we'd expect" do
|
109
109
|
post = Post.new :title => "Amish Give Up - 'This is bullshit!', Elders Say",
|
110
110
|
:byline => "The Onion",
|
@@ -117,7 +117,7 @@ describe "Base models", :model => true do
|
|
117
117
|
post.byline.should == "The Onion"
|
118
118
|
post.content.should =~ /Lorem ipsum dolor/
|
119
119
|
end
|
120
|
-
|
120
|
+
|
121
121
|
it "should be able to convert itself to a hash" do
|
122
122
|
post = Post.new :title => "A title",
|
123
123
|
:byline => "Max",
|
@@ -127,7 +127,7 @@ describe "Base models", :model => true do
|
|
127
127
|
hash[:byline].should == "Max"
|
128
128
|
hash[:content].should == "Some content"
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
it "should have a 'save' and 'reload' method that work like we'd expect" do
|
132
132
|
post = Post.new :title => "A title",
|
133
133
|
:byline => "Max",
|
@@ -140,25 +140,25 @@ describe "Base models", :model => true do
|
|
140
140
|
post.byline.should == "Max"
|
141
141
|
post.content.should == "Some content"
|
142
142
|
end
|
143
|
-
|
143
|
+
|
144
144
|
it "should refuse to reload a new record, that hasn't yet been saved" do
|
145
145
|
post = Post.new :title => "A title",
|
146
146
|
:byline => "Max",
|
147
147
|
:content => "Some content"
|
148
148
|
(->{post.reload}).should raise_error
|
149
149
|
end
|
150
|
-
|
150
|
+
|
151
151
|
it "should be able to tell when two records are equivalent" do
|
152
152
|
foo = Post.create :title => "Kitties!", :byline => "Max", :content => "Kitties are awesome."
|
153
153
|
bar = Post.create :title => "Doggies!", :byline => "Max", :content => "Doggies are cool."
|
154
|
-
|
154
|
+
|
155
155
|
foo.should == foo
|
156
156
|
foo.should_not == bar
|
157
|
-
|
157
|
+
|
158
158
|
foo.should eql(foo)
|
159
159
|
foo.should_not eql(bar)
|
160
160
|
end
|
161
|
-
|
161
|
+
|
162
162
|
it "should also be able to determine the hash of a record, for equivalence testing" do
|
163
163
|
Post.new(title: "Guinea Pigs", byline: "Max", content: "Guinea pigs are super cute.").hash.is_a?(Fixnum).should be_true
|
164
164
|
end
|
@@ -171,7 +171,7 @@ describe "Base models", :model => true do
|
|
171
171
|
post.save
|
172
172
|
post.new?.should be_false
|
173
173
|
end
|
174
|
-
|
174
|
+
|
175
175
|
# context 'deletion' do
|
176
176
|
it "should be deleteable from the model class", wip:true do
|
177
177
|
post = Post.create :title => "This post should be deleted",
|
@@ -185,7 +185,7 @@ describe "Base models", :model => true do
|
|
185
185
|
deleted_post.should be_destroyed
|
186
186
|
Post.find(id).should be_nil
|
187
187
|
end
|
188
|
-
|
188
|
+
|
189
189
|
it "should be destroyable by itself" do
|
190
190
|
another_post = Post.create :title => "This one too, probably.",
|
191
191
|
:byline => "Just seems like one big",
|
@@ -196,7 +196,7 @@ describe "Base models", :model => true do
|
|
196
196
|
Post.find(id).should be_nil
|
197
197
|
end
|
198
198
|
# end
|
199
|
-
|
199
|
+
|
200
200
|
it "should be findable by ID" do
|
201
201
|
post = Post.create :title => "foo",
|
202
202
|
:byline => "bar",
|
@@ -204,7 +204,7 @@ describe "Base models", :model => true do
|
|
204
204
|
Post.find(post.id).should == post
|
205
205
|
# Since we're using GUIDs, this should also be true:
|
206
206
|
post2 = Post.find(post.id)
|
207
|
-
|
207
|
+
|
208
208
|
post.title.should == post2.title
|
209
209
|
post.byline.should == post2.byline
|
210
210
|
post.content.should == post2.content
|
@@ -217,22 +217,22 @@ describe "Base models", :model => true do
|
|
217
217
|
post.should be_persisted
|
218
218
|
Post.find(post.id).should == post
|
219
219
|
end
|
220
|
-
|
220
|
+
|
221
221
|
it "should return an integer for its ID" do
|
222
222
|
post = Post.create :title => "On Motorcycles and Robots",
|
223
223
|
:byline => "Max",
|
224
224
|
:content => "Motorcycles and robots are awesome"
|
225
225
|
post.id.should be_a(Fixnum)
|
226
226
|
end
|
227
|
-
|
227
|
+
|
228
228
|
# # #
|
229
|
-
|
229
|
+
|
230
230
|
after :all do
|
231
231
|
# Clear out Redis
|
232
232
|
Redis.new.flushall
|
233
233
|
Ampere.disconnect
|
234
234
|
end
|
235
|
-
|
235
|
+
|
236
236
|
end
|
237
|
-
|
238
|
-
end
|
237
|
+
|
238
|
+
end
|
data/spec/models/queries_spec.rb
CHANGED
@@ -4,19 +4,19 @@ describe 'queries', :queries => true do
|
|
4
4
|
before :each do
|
5
5
|
Redis.new.flushall
|
6
6
|
Ampere.connect
|
7
|
-
|
7
|
+
|
8
8
|
class Kitty
|
9
9
|
include Ampere::Model
|
10
|
-
|
10
|
+
|
11
11
|
field :name
|
12
12
|
field :breed
|
13
13
|
field :age
|
14
14
|
field :color
|
15
|
-
|
15
|
+
|
16
16
|
index :name # => Unique
|
17
17
|
index :color # => Non-unique
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
@kitty_paws = Kitty.create name: 'Kitty Paws',
|
21
21
|
breed: 'Domestic shorthair',
|
22
22
|
age: 19,
|
@@ -39,13 +39,13 @@ describe 'queries', :queries => true do
|
|
39
39
|
color: 'grey'
|
40
40
|
[@kitty_paws, @nate, @jinxii, @italics, @serif]. each {|k| k.reload}
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
###
|
44
|
-
|
44
|
+
|
45
45
|
it 'should pass a basic sanity check' do
|
46
46
|
Kitty.count.should == 5
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
it 'should be able to select all kitties' do
|
50
50
|
Kitty.all.map(&:name).should include('Kitty Paws')
|
51
51
|
Kitty.all.map(&:name).should include('Nate')
|
@@ -53,35 +53,35 @@ describe 'queries', :queries => true do
|
|
53
53
|
Kitty.all.map(&:name).should include('Italics')
|
54
54
|
Kitty.all.map(&:name).should include('Serif')
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
context 'with no fields' do
|
58
58
|
it 'should return the empty set with no conditions given' do
|
59
59
|
Kitty.where().should be_empty
|
60
60
|
end
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
context 'with one field' do
|
64
64
|
it 'should be able to find by an indexed field using where()' do
|
65
65
|
Kitty.where(:name => 'Nate').to_a.map(&:name).should include('Nate')
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
it 'should be able to find by a non-indexed field using where()' do
|
69
69
|
Kitty.where(:breed => 'Siberian').to_a.map(&:name).should include('Italics')
|
70
70
|
Kitty.where(:breed => 'Siberian').to_a.map(&:name).should include('Serif')
|
71
71
|
end
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
it 'should be able to find by two indexed fields at once' do
|
75
75
|
kitty = Kitty.where(:name => "Kitty Paws", :color => "orange")
|
76
76
|
kitty.count.should == 1
|
77
77
|
kitty.first.name.should == "Kitty Paws"
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
it 'should be able to find by two non-indexed fields at once' do
|
81
81
|
# :breed and :age are not indexed
|
82
82
|
Kitty.where(:breed => "Domestic shorthair", :age => 17).count.should == 1
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
it 'should be able to find by a mix of indexed and non-indexed fields' do
|
86
86
|
# :color is indexed, :breed is not
|
87
87
|
Kitty.where(:color => "orange").count.should == 2
|
@@ -89,9 +89,9 @@ describe 'queries', :queries => true do
|
|
89
89
|
Kitty.where(:color => "orange", :breed => "Siberian").count.should == 1
|
90
90
|
Kitty.where(:color => "orange", :breed => "Siberian").first.name.should == "Italics"
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
###
|
94
|
-
|
94
|
+
|
95
95
|
after :all do
|
96
96
|
Redis.new.flushall
|
97
97
|
Ampere.connect
|
@@ -1,41 +1,41 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "..", "..", "spec_helper.rb")
|
2
2
|
|
3
3
|
describe 'belongs_to relationships', :belongs_to => true do
|
4
|
+
|
5
|
+
class Car
|
6
|
+
include Ampere::Model
|
7
|
+
|
8
|
+
field :make
|
9
|
+
field :model
|
10
|
+
field :year
|
11
|
+
|
12
|
+
has_one :engine
|
13
|
+
has_many :passengers
|
14
|
+
end
|
15
|
+
|
16
|
+
class Engine
|
17
|
+
include Ampere::Model
|
18
|
+
|
19
|
+
field :displacement
|
20
|
+
field :cylinders
|
21
|
+
field :configuration
|
22
|
+
|
23
|
+
belongs_to :car
|
24
|
+
end
|
25
|
+
|
26
|
+
class Passenger
|
27
|
+
include Ampere::Model
|
28
|
+
|
29
|
+
field :name
|
30
|
+
field :seat
|
31
|
+
|
32
|
+
belongs_to :car
|
33
|
+
end
|
34
|
+
|
4
35
|
before :all do
|
5
36
|
Redis.new.flushall
|
6
37
|
Ampere.connect
|
7
38
|
|
8
|
-
# These are used by the has_one/belongs_to example below
|
9
|
-
class Car
|
10
|
-
include Ampere::Model
|
11
|
-
|
12
|
-
field :make
|
13
|
-
field :model
|
14
|
-
field :year
|
15
|
-
|
16
|
-
has_one :engine
|
17
|
-
has_many :passengers
|
18
|
-
end
|
19
|
-
|
20
|
-
class Engine
|
21
|
-
include Ampere::Model
|
22
|
-
|
23
|
-
field :displacement
|
24
|
-
field :cylinders
|
25
|
-
field :configuration
|
26
|
-
|
27
|
-
belongs_to :car
|
28
|
-
end
|
29
|
-
|
30
|
-
class Passenger
|
31
|
-
include Ampere::Model
|
32
|
-
|
33
|
-
field :name
|
34
|
-
field :seat
|
35
|
-
|
36
|
-
belongs_to :car
|
37
|
-
end
|
38
|
-
|
39
39
|
@car = Car.create :make => "Lamborghini",
|
40
40
|
:model => "Countach",
|
41
41
|
:year => "1974"
|
@@ -47,66 +47,66 @@ describe 'belongs_to relationships', :belongs_to => true do
|
|
47
47
|
@passenger = Passenger.create :name => "Leila",
|
48
48
|
:seat => "passenger"
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
###
|
52
|
-
|
52
|
+
|
53
53
|
it 'sets accessor methods for a belongs_to relationship' do
|
54
54
|
# Other side of a has_many
|
55
55
|
@driver.should respond_to(:car)
|
56
56
|
# Other side of a has_one
|
57
57
|
@engine.should respond_to(:car)
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
it 'sets belongs_to pointer for has_one relationship that is set from the parent' do
|
61
61
|
@car.engine = @engine
|
62
62
|
@car.save
|
63
63
|
@engine.save
|
64
|
-
|
64
|
+
|
65
65
|
car = Car.find(@car.id)
|
66
66
|
engine = Engine.find(@engine.id)
|
67
|
-
|
67
|
+
|
68
68
|
car.engine.should == @engine
|
69
69
|
engine.car.should == @car
|
70
|
-
|
70
|
+
|
71
71
|
# Cleanup
|
72
72
|
@car.engine = nil
|
73
73
|
@engine.car = nil
|
74
74
|
@car.save
|
75
75
|
@engine.save
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
it 'sets belongs_to pointer for has_one relationship that is set from the child' do
|
79
79
|
@engine.car = @car
|
80
80
|
@car.save
|
81
81
|
@engine.save
|
82
|
-
|
82
|
+
|
83
83
|
car = Car.find(@car.id)
|
84
84
|
engine = Engine.find(@engine.id)
|
85
|
-
|
85
|
+
|
86
86
|
car.engine.should == @engine
|
87
87
|
engine.car.should == @car
|
88
|
-
|
88
|
+
|
89
89
|
# Cleanup
|
90
90
|
@car.engine = nil
|
91
91
|
@engine.car = nil
|
92
92
|
@car.save
|
93
93
|
@engine.save
|
94
94
|
end
|
95
|
-
|
95
|
+
|
96
96
|
it 'sets belongs_to pointer for has_many relationship' do
|
97
97
|
@car.passengers = @car.passengers + [@driver]
|
98
98
|
@car.passengers = @car.passengers + [@passenger]
|
99
99
|
@car.save
|
100
|
-
|
100
|
+
|
101
101
|
@driver.reload
|
102
102
|
@passenger.reload
|
103
|
-
|
103
|
+
|
104
104
|
@driver.car.should == @car
|
105
105
|
@passenger.car.should == @car
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
###
|
109
|
-
|
109
|
+
|
110
110
|
after :all do
|
111
111
|
Redis.new.flushall
|
112
112
|
Ampere.connect
|
@@ -1,30 +1,30 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "..", "..", "spec_helper.rb")
|
2
2
|
|
3
3
|
describe 'has_many relationships', :has_many => true do
|
4
|
+
|
5
|
+
class Car
|
6
|
+
include Ampere::Model
|
7
|
+
|
8
|
+
field :make
|
9
|
+
field :model
|
10
|
+
field :year
|
11
|
+
|
12
|
+
has_many :passengers
|
13
|
+
end
|
14
|
+
|
15
|
+
class Passenger
|
16
|
+
include Ampere::Model
|
17
|
+
|
18
|
+
field :name
|
19
|
+
field :seat
|
20
|
+
|
21
|
+
belongs_to :car
|
22
|
+
end
|
23
|
+
|
4
24
|
before :each do
|
5
25
|
Redis.new.flushall
|
6
26
|
Ampere.connect
|
7
|
-
|
8
|
-
# These are used by the has_one/belongs_to example below
|
9
|
-
class Car
|
10
|
-
include Ampere::Model
|
11
|
-
|
12
|
-
field :make
|
13
|
-
field :model
|
14
|
-
field :year
|
15
|
-
|
16
|
-
has_many :passengers
|
17
|
-
end
|
18
|
-
|
19
|
-
class Passenger
|
20
|
-
include Ampere::Model
|
21
|
-
|
22
|
-
field :name
|
23
|
-
field :seat
|
24
|
-
|
25
|
-
belongs_to :car
|
26
|
-
end
|
27
|
-
|
27
|
+
|
28
28
|
@car = Car.create :make => "Lamborghini",
|
29
29
|
:model => "Countach",
|
30
30
|
:year => "1974"
|
@@ -34,22 +34,22 @@ describe 'has_many relationships', :has_many => true do
|
|
34
34
|
:seat => "passenger"
|
35
35
|
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
###
|
39
|
-
|
39
|
+
|
40
40
|
it 'should define the necessary methods for has_many relationships' do
|
41
41
|
# Attr accessors
|
42
42
|
@car.should respond_to(:passengers)
|
43
43
|
@car.should respond_to(:"passengers=")
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
it 'should be able to add items to has_many relationships' do
|
47
47
|
@car.passengers = @car.passengers + [@driver]
|
48
48
|
@car.passengers = @car.passengers + [@passenger]
|
49
49
|
|
50
50
|
@car.save
|
51
51
|
@car.reload
|
52
|
-
|
52
|
+
|
53
53
|
@driver.reload
|
54
54
|
@passenger.reload
|
55
55
|
|
@@ -57,19 +57,24 @@ describe 'has_many relationships', :has_many => true do
|
|
57
57
|
@car.passengers.should include(@passenger)
|
58
58
|
end
|
59
59
|
|
60
|
+
it 'should add a set of IDs to Redis', wip:true do
|
61
|
+
@car.passengers = @car.passengers + [@driver]
|
62
|
+
Ampere.connection.keys.should include("car.#{@car.id}.has_many.passengers")
|
63
|
+
end
|
64
|
+
|
60
65
|
# it 'should be able to remove items from has_many relationships' do
|
61
66
|
# pending
|
62
67
|
# end
|
63
|
-
|
68
|
+
|
64
69
|
# it 'should be able to query has_many relationships' do
|
65
70
|
# pending
|
66
71
|
# end
|
67
|
-
|
72
|
+
|
68
73
|
###
|
69
|
-
|
74
|
+
|
70
75
|
after :all do
|
71
76
|
Ampere.disconnect
|
72
77
|
Redis.new.flushall
|
73
78
|
end
|
74
|
-
|
79
|
+
|
75
80
|
end
|
@@ -1,31 +1,32 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "..", "..", "spec_helper.rb")
|
2
2
|
|
3
3
|
describe 'has_one relationships', has_one:true do
|
4
|
+
|
5
|
+
class Car
|
6
|
+
include Ampere::Model
|
7
|
+
|
8
|
+
field :make
|
9
|
+
field :model
|
10
|
+
field :year
|
11
|
+
|
12
|
+
has_one :engine
|
13
|
+
end
|
14
|
+
|
15
|
+
class Engine
|
16
|
+
include Ampere::Model
|
17
|
+
|
18
|
+
field :displacement
|
19
|
+
field :cylinders
|
20
|
+
field :configuration
|
21
|
+
|
22
|
+
belongs_to :car
|
23
|
+
end
|
24
|
+
|
25
|
+
|
4
26
|
before :all do
|
5
27
|
Redis.new.flushall
|
6
28
|
Ampere.connect
|
7
29
|
|
8
|
-
# These are used by the has_one/belongs_to example below
|
9
|
-
class Car
|
10
|
-
include Ampere::Model
|
11
|
-
|
12
|
-
field :make
|
13
|
-
field :model
|
14
|
-
field :year
|
15
|
-
|
16
|
-
has_one :engine
|
17
|
-
end
|
18
|
-
|
19
|
-
class Engine
|
20
|
-
include Ampere::Model
|
21
|
-
|
22
|
-
field :displacement
|
23
|
-
field :cylinders
|
24
|
-
field :configuration
|
25
|
-
|
26
|
-
belongs_to :car
|
27
|
-
end
|
28
|
-
|
29
30
|
@car = Car.create :make => "Lamborghini",
|
30
31
|
:model => "Countach",
|
31
32
|
:year => "1974"
|
@@ -33,9 +34,9 @@ describe 'has_one relationships', has_one:true do
|
|
33
34
|
:cylinders => "12",
|
34
35
|
:configuration => "V"
|
35
36
|
end
|
36
|
-
|
37
|
+
|
37
38
|
###
|
38
|
-
|
39
|
+
|
39
40
|
it 'can store a relationship to one model instance from another using an attr_accessor' do
|
40
41
|
@car.engine_id = @engine.id
|
41
42
|
@car.save
|
@@ -43,12 +44,12 @@ describe 'has_one relationships', has_one:true do
|
|
43
44
|
@engine.reload
|
44
45
|
@car.engine_id.should == @engine.id
|
45
46
|
@car.engine.should == @engine
|
46
|
-
|
47
|
+
|
47
48
|
@car.engine_id = nil
|
48
49
|
@car.save
|
49
50
|
@car.engine.should be_nil
|
50
51
|
end
|
51
|
-
|
52
|
+
|
52
53
|
it 'can store a relationship to one model instance from another using custom accessor methods' do
|
53
54
|
@car.engine = @engine
|
54
55
|
@car.save
|
@@ -56,12 +57,12 @@ describe 'has_one relationships', has_one:true do
|
|
56
57
|
@engine.reload
|
57
58
|
@car.engine_id.should == @engine.id
|
58
59
|
@car.engine.should == @engine
|
59
|
-
|
60
|
+
|
60
61
|
@car.engine_id = nil
|
61
62
|
@car.save
|
62
63
|
@car.engine.should be_nil
|
63
64
|
end
|
64
|
-
|
65
|
+
|
65
66
|
it 'can delete the object related to it in a has_one relationship' do
|
66
67
|
@car.engine = @engine
|
67
68
|
@car.engine.destroy
|
@@ -69,11 +70,11 @@ describe 'has_one relationships', has_one:true do
|
|
69
70
|
@car.engine.should be_nil
|
70
71
|
Engine.find(@engine.id).should be_nil
|
71
72
|
end
|
72
|
-
|
73
|
+
|
73
74
|
###
|
74
|
-
|
75
|
+
|
75
76
|
after :all do
|
76
77
|
Ampere.disconnect
|
77
78
|
Redis.new.flushall
|
78
79
|
end
|
79
|
-
end
|
80
|
+
end
|
@@ -1,45 +1,45 @@
|
|
1
1
|
describe Ampere::Timestamps do
|
2
2
|
before :all do
|
3
3
|
Ampere.connect
|
4
|
-
|
4
|
+
|
5
5
|
Ampere.connection.flushall
|
6
|
-
|
6
|
+
|
7
7
|
class Comment
|
8
8
|
include Ampere::Model
|
9
9
|
include Ampere::Timestamps
|
10
|
-
|
10
|
+
|
11
11
|
field :body
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
context 'when included in models' do
|
16
16
|
it 'sets created_at for newly-created record' do
|
17
17
|
Timecop.freeze(Time.now) do
|
18
18
|
time = Time.now
|
19
|
-
|
19
|
+
|
20
20
|
c = Comment.create body: "I am intrigued by your ideas, and would like to subscribe to your newsletter."
|
21
21
|
c.created_at.should eq(time)
|
22
22
|
c.updated_at.should eq(time)
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
it 'sets updated_at when changing records' do
|
27
27
|
c = Comment.create body: "I am intrigued by your ideas, and would like to subscribe to your newsletter."
|
28
28
|
created_at = c.created_at
|
29
|
-
|
29
|
+
|
30
30
|
time = 0
|
31
|
-
|
31
|
+
|
32
32
|
Timecop.freeze(Time.now + 30) do
|
33
33
|
time = Time.now
|
34
|
-
|
34
|
+
|
35
35
|
c.body = "Theodore Roosevelt riding a moose, therefore your argument is invalid."
|
36
36
|
c.save
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
c.updated_at.should eq(time)
|
40
40
|
c.created_at.should eq(created_at)
|
41
41
|
end
|
42
|
-
|
43
|
-
end
|
44
42
|
|
43
|
+
end
|
44
|
+
|
45
45
|
end
|
data/spec/models/updates_spec.rb
CHANGED
@@ -4,33 +4,33 @@ describe 'queries', :queries => true do
|
|
4
4
|
before :each do
|
5
5
|
Redis.new.flushall
|
6
6
|
Ampere.connect
|
7
|
-
|
7
|
+
|
8
8
|
class Motorcycle
|
9
9
|
include Ampere::Model
|
10
|
-
|
10
|
+
|
11
11
|
field :make
|
12
12
|
field :model
|
13
13
|
field :year
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
@bike = Motorcycle.create make: "Honda", model: "CB400", year: "1990"
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
###
|
20
|
-
|
20
|
+
|
21
21
|
it 'should be able to update one field atomically' do
|
22
22
|
@bike.model.should == "CB400"
|
23
23
|
@bike.update_attribute :model, "CB450SC"
|
24
24
|
@bike.model.should == "CB450SC"
|
25
25
|
@bike.reload.model.should == "CB450SC"
|
26
|
-
|
26
|
+
|
27
27
|
@bike.year.should == "1990"
|
28
28
|
@bike.update_attribute :year, "1986"
|
29
29
|
@bike.year.should == "1986"
|
30
30
|
@bike.reload
|
31
31
|
@bike.year.should == "1986"
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
it 'should be able to update multiple fields atomically' do
|
35
35
|
@bike.update_attributes model: "CB750",
|
36
36
|
year: "1996"
|
@@ -54,9 +54,9 @@ describe 'queries', :queries => true do
|
|
54
54
|
neither_does_this_one: "Duis aute irure dolor in."
|
55
55
|
}).should raise_error
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
###
|
59
|
-
|
59
|
+
|
60
60
|
after :all do
|
61
61
|
Redis.new.flushall
|
62
62
|
Ampere.connect
|
@@ -4,17 +4,17 @@ describe 'Validations', :validations => true do
|
|
4
4
|
before :all do
|
5
5
|
class Person
|
6
6
|
include Ampere::Model
|
7
|
-
|
7
|
+
|
8
8
|
field :first_name
|
9
9
|
field :last_name
|
10
10
|
field :email
|
11
|
-
|
11
|
+
|
12
12
|
validates_presence_of :last_name
|
13
13
|
validates_format_of :email, :with => /\A\w+@\w+\.com\Z/i
|
14
14
|
end
|
15
|
-
|
16
|
-
end
|
17
15
|
|
16
|
+
end
|
17
|
+
|
18
18
|
it 'should validate presence of items' do
|
19
19
|
alice = Person.new :first_name => 'Alice',
|
20
20
|
:last_name => 'Steel',
|
@@ -26,16 +26,15 @@ describe 'Validations', :validations => true do
|
|
26
26
|
bob.should be_invalid
|
27
27
|
bob.errors.should_not be_empty
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it 'should validate format of items' do
|
31
31
|
charlie = Person.new :first_name => 'Charlie',
|
32
32
|
:last_name => 'Steel',
|
33
33
|
:email => 'c h a r l i e @ charlie .com'
|
34
34
|
charlie.should_not be_valid
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
# Since this is accomplished by including a module, what is being tested here
|
38
38
|
# is that the module got included correctly and works. For testing of all the
|
39
39
|
# other kinds of validations, run the tests for ActiveModel::Validations.
|
40
40
|
end
|
41
|
-
|
@@ -4,13 +4,13 @@ describe 'Collections are Ennumerable', :collections => true, :ennumerable => tr
|
|
4
4
|
before :all do
|
5
5
|
Redis.new.flushall
|
6
6
|
Ampere.connect
|
7
|
-
|
7
|
+
|
8
8
|
class President
|
9
9
|
include Ampere::Model
|
10
|
-
|
10
|
+
|
11
11
|
field :name
|
12
12
|
field :party
|
13
|
-
|
13
|
+
|
14
14
|
index :party
|
15
15
|
end
|
16
16
|
|
@@ -21,32 +21,32 @@ describe 'Collections are Ennumerable', :collections => true, :ennumerable => tr
|
|
21
21
|
President.create :name => "John F. Kennedy" , :party => "Democratic"
|
22
22
|
President.create :name => "Jimmy Carter" , :party => "Democratic"
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it 'should implement the #each method correctly' do
|
26
26
|
presidents = []
|
27
27
|
President.all.each {|p| presidents << p.name}
|
28
|
-
presidents.should == [
|
29
|
-
"Millard Fillmore" ,
|
30
|
-
"Ulysses S. Grant" ,
|
28
|
+
presidents.sort.should == [
|
31
29
|
"Abraham Lincoln" ,
|
32
30
|
"Franklin D. Roosevelt",
|
31
|
+
"Jimmy Carter" ,
|
33
32
|
"John F. Kennedy" ,
|
34
|
-
"
|
33
|
+
"Millard Fillmore" ,
|
34
|
+
"Ulysses S. Grant"
|
35
35
|
]
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it 'should lazily evaluate the #[] method' do
|
39
39
|
presidents = President.all
|
40
|
-
|
40
|
+
|
41
41
|
presidents[2].name.should eq('Abraham Lincoln')
|
42
42
|
presidents[2].name.should eq('Abraham Lincoln')
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
it 'should be comparable to an array' do
|
46
46
|
President.all.should == President.all.to_a
|
47
47
|
President.all.should_not be(President.all.to_a)
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
# These are just a handful of methods to ensure that the Enumerable module is
|
51
51
|
# being included correctly. They can safely be factored out since the #each
|
52
52
|
# one above should cover Enumerable if it's being included correctly.
|
@@ -59,9 +59,9 @@ describe 'Collections are Ennumerable', :collections => true, :ennumerable => tr
|
|
59
59
|
President.all.any? {|p| p.party == 'Whig'}.should be_true
|
60
60
|
President.all.any? {|p| p.party == 'Green'}.should be_false
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
it 'should implement the #map method correctly' do
|
64
|
-
President.all.map(&:party).should == %w{Whig Republican Republican Democratic Democratic Democratic}
|
64
|
+
President.all.map(&:party).sort.should == %w{Whig Republican Republican Democratic Democratic Democratic}.sort
|
65
65
|
end
|
66
66
|
|
67
67
|
it 'should implement the #inject method correctly' do
|
@@ -77,6 +77,6 @@ describe 'Collections are Ennumerable', :collections => true, :ennumerable => tr
|
|
77
77
|
}
|
78
78
|
end
|
79
79
|
|
80
|
-
|
80
|
+
|
81
81
|
end
|
82
82
|
|
@@ -3,13 +3,13 @@ require File.join(File.dirname(__FILE__), "..", "spec_helper.rb")
|
|
3
3
|
describe 'Collections', :collections => true do
|
4
4
|
class President
|
5
5
|
include Ampere::Model
|
6
|
-
|
6
|
+
|
7
7
|
field :name
|
8
8
|
field :party
|
9
|
-
|
9
|
+
|
10
10
|
index :party
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
before :all do
|
14
14
|
Redis.new.flushall
|
15
15
|
Ampere.connect
|
@@ -21,7 +21,7 @@ describe 'Collections', :collections => true do
|
|
21
21
|
President.create :name => "John F. Kennedy" , :party => "Democratic"
|
22
22
|
President.create :name => "Jimmy Carter" , :party => "Democratic"
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
###
|
26
26
|
|
27
27
|
it 'should be returned by President.all' do
|
@@ -31,7 +31,7 @@ describe 'Collections', :collections => true do
|
|
31
31
|
democrats.raw_array.length.should == 6
|
32
32
|
democrats.count.should == 6
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
it 'should be returned by where() queries' do
|
36
36
|
democrats = President.where(:party => "Democratic")
|
37
37
|
democrats.class.should == Ampere::Collection
|
@@ -39,46 +39,46 @@ describe 'Collections', :collections => true do
|
|
39
39
|
democrats.raw_array.length.should == 3
|
40
40
|
democrats.count.should == 3
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it 'should be accessible via [] like an Array' do
|
44
44
|
whigs = President.where(:party => "Whig")
|
45
45
|
whigs[0].name.should == "Millard Fillmore"
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
it 'should lazily load model instances searched for with indexed fields' do
|
49
49
|
whigs = President.where(:party => "Whig")
|
50
50
|
whigs.raw_array.first.class.should == String
|
51
51
|
whigs[0].name.should == "Millard Fillmore"
|
52
52
|
whigs.raw_array.first.class.should == President
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
it 'should return its first() item' do
|
56
56
|
republicans = President.where(:party => "Republican")
|
57
57
|
republicans.first.name.should == "Ulysses S. Grant"
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
it 'should return its first(n) items' do
|
61
61
|
republicans = President.where(:party => "Republican")
|
62
62
|
republicans.first(2).map(&:name).should == ["Ulysses S. Grant", "Abraham Lincoln"]
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
it 'should return its last() item' do
|
66
66
|
democrats = President.where(:party => "Democratic")
|
67
67
|
democrats.last.name.should == "Jimmy Carter"
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
it 'should be convertible to an array' do
|
71
71
|
republicans = President.where(:party => "Republican")
|
72
72
|
republicans.to_a.map(&:name).should == ["Ulysses S. Grant", "Abraham Lincoln"]
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
it 'should give its first and last elements non-lazily' do
|
76
76
|
President.first.name.should eq("Millard Fillmore")
|
77
77
|
President.last.name.should eq("Jimmy Carter")
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
###
|
81
|
-
|
81
|
+
|
82
82
|
after :all do
|
83
83
|
Ampere.disconnect
|
84
84
|
Redis.new.flushall
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ampere
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -315,7 +315,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
315
315
|
version: '0'
|
316
316
|
segments:
|
317
317
|
- 0
|
318
|
-
hash:
|
318
|
+
hash: 2670808373290565057
|
319
319
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
320
320
|
none: false
|
321
321
|
requirements:
|