massive_record 0.1.1 → 0.2.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/CHANGELOG.md +28 -5
  2. data/Gemfile.lock +12 -12
  3. data/README.md +29 -1
  4. data/lib/massive_record/adapters/initialize.rb +18 -0
  5. data/lib/massive_record/adapters/thrift/adapter.rb +25 -0
  6. data/lib/massive_record/adapters/thrift/column_family.rb +24 -0
  7. data/lib/massive_record/adapters/thrift/connection.rb +73 -0
  8. data/lib/massive_record/{thrift → adapters/thrift/hbase}/hbase.rb +0 -0
  9. data/lib/massive_record/{thrift → adapters/thrift/hbase}/hbase_constants.rb +0 -0
  10. data/lib/massive_record/{thrift → adapters/thrift/hbase}/hbase_types.rb +0 -0
  11. data/lib/massive_record/adapters/thrift/row.rb +150 -0
  12. data/lib/massive_record/adapters/thrift/scanner.rb +59 -0
  13. data/lib/massive_record/adapters/thrift/table.rb +169 -0
  14. data/lib/massive_record/orm/attribute_methods/read.rb +2 -1
  15. data/lib/massive_record/orm/base.rb +61 -3
  16. data/lib/massive_record/orm/coders/chained.rb +71 -0
  17. data/lib/massive_record/orm/coders/json.rb +17 -0
  18. data/lib/massive_record/orm/coders/yaml.rb +15 -0
  19. data/lib/massive_record/orm/coders.rb +3 -0
  20. data/lib/massive_record/orm/errors.rb +15 -2
  21. data/lib/massive_record/orm/finders/scope.rb +166 -0
  22. data/lib/massive_record/orm/finders.rb +45 -24
  23. data/lib/massive_record/orm/persistence.rb +4 -4
  24. data/lib/massive_record/orm/relations/interface.rb +170 -0
  25. data/lib/massive_record/orm/relations/metadata.rb +150 -0
  26. data/lib/massive_record/orm/relations/proxy/references_many.rb +229 -0
  27. data/lib/massive_record/orm/relations/proxy/references_one.rb +40 -0
  28. data/lib/massive_record/orm/relations/proxy/references_one_polymorphic.rb +49 -0
  29. data/lib/massive_record/orm/relations/proxy.rb +174 -0
  30. data/lib/massive_record/orm/relations.rb +6 -0
  31. data/lib/massive_record/orm/schema/column_interface.rb +1 -1
  32. data/lib/massive_record/orm/schema/field.rb +62 -27
  33. data/lib/massive_record/orm/single_table_inheritance.rb +21 -0
  34. data/lib/massive_record/version.rb +1 -1
  35. data/lib/massive_record/wrapper/adapter.rb +6 -0
  36. data/lib/massive_record/wrapper/base.rb +6 -7
  37. data/lib/massive_record/wrapper/cell.rb +9 -32
  38. data/lib/massive_record/wrapper/column_families_collection.rb +2 -2
  39. data/lib/massive_record/wrapper/errors.rb +10 -0
  40. data/lib/massive_record/wrapper/tables_collection.rb +1 -1
  41. data/lib/massive_record.rb +5 -12
  42. data/spec/orm/cases/attribute_methods_spec.rb +5 -1
  43. data/spec/orm/cases/base_spec.rb +77 -4
  44. data/spec/orm/cases/column_spec.rb +1 -1
  45. data/spec/orm/cases/finder_default_scope.rb +53 -0
  46. data/spec/orm/cases/finder_scope_spec.rb +288 -0
  47. data/spec/orm/cases/finders_spec.rb +56 -13
  48. data/spec/orm/cases/persistence_spec.rb +20 -5
  49. data/spec/orm/cases/single_table_inheritance_spec.rb +26 -0
  50. data/spec/orm/cases/table_spec.rb +1 -1
  51. data/spec/orm/cases/timestamps_spec.rb +16 -16
  52. data/spec/orm/coders/chained_spec.rb +73 -0
  53. data/spec/orm/coders/json_spec.rb +6 -0
  54. data/spec/orm/coders/yaml_spec.rb +6 -0
  55. data/spec/orm/models/best_friend.rb +7 -0
  56. data/spec/orm/models/friend.rb +4 -0
  57. data/spec/orm/models/person.rb +20 -6
  58. data/spec/orm/models/{person_with_timestamps.rb → person_with_timestamp.rb} +1 -1
  59. data/spec/orm/models/test_class.rb +3 -0
  60. data/spec/orm/relations/interface_spec.rb +207 -0
  61. data/spec/orm/relations/metadata_spec.rb +202 -0
  62. data/spec/orm/relations/proxy/references_many_spec.rb +624 -0
  63. data/spec/orm/relations/proxy/references_one_polymorphic_spec.rb +106 -0
  64. data/spec/orm/relations/proxy/references_one_spec.rb +111 -0
  65. data/spec/orm/relations/proxy_spec.rb +13 -0
  66. data/spec/orm/schema/field_spec.rb +101 -2
  67. data/spec/shared/orm/coders/an_orm_coder.rb +14 -0
  68. data/spec/shared/orm/relations/proxy.rb +154 -0
  69. data/spec/shared/orm/relations/singular_proxy.rb +68 -0
  70. data/spec/spec_helper.rb +1 -0
  71. data/spec/thrift/cases/encoding_spec.rb +28 -7
  72. data/spec/wrapper/cases/adapter_spec.rb +9 -0
  73. data/spec/wrapper/cases/connection_spec.rb +13 -10
  74. data/spec/wrapper/cases/table_spec.rb +85 -85
  75. metadata +74 -22
  76. data/TODO.md +0 -8
  77. data/lib/massive_record/exceptions.rb +0 -11
  78. data/lib/massive_record/wrapper/column_family.rb +0 -22
  79. data/lib/massive_record/wrapper/connection.rb +0 -71
  80. data/lib/massive_record/wrapper/row.rb +0 -173
  81. data/lib/massive_record/wrapper/scanner.rb +0 -61
  82. data/lib/massive_record/wrapper/table.rb +0 -149
  83. data/spec/orm/cases/hbase/connection_spec.rb +0 -13
@@ -7,7 +7,7 @@ describe "finders" do
7
7
  include MockMassiveRecordConnection
8
8
 
9
9
  before do
10
- @mocked_table = mock(MassiveRecord::Wrapper::Table).as_null_object
10
+ @mocked_table = mock(MassiveRecord::Wrapper::Table, :to_ary => []).as_null_object
11
11
  Person.stub(:table).and_return(@mocked_table)
12
12
 
13
13
  @row = MassiveRecord::Wrapper::Row.new
@@ -28,9 +28,9 @@ describe "finders" do
28
28
  Person.first.should be_nil
29
29
  end
30
30
 
31
- it "should simply return nil on find if table does not exists" do
31
+ it "should raise record not found error on find if table does not exists" do
32
32
  Person.table.should_receive(:exists?).and_return false
33
- Person.find(1).should be_nil
33
+ lambda { Person.find(1) }.should raise_error MassiveRecord::ORM::RecordNotFound
34
34
  end
35
35
 
36
36
  it "should simply return empty array if table does not exists" do
@@ -98,7 +98,6 @@ describe "finders" do
98
98
  end
99
99
 
100
100
  it "should return nil on first if no results was found" do
101
- @mocked_table.should_receive(:first).and_return(nil)
102
101
  Person.first.should be_nil
103
102
  end
104
103
 
@@ -113,20 +112,37 @@ describe "finders" do
113
112
  end
114
113
  end
115
114
 
116
- %w(first all).each do |method|
117
- it "should respond to #{method}" do
118
- TestClass.should respond_to method
115
+ describe "all" do
116
+ it "should respond to all" do
117
+ TestClass.should respond_to :all
119
118
  end
120
119
 
121
- it "should delegate #{method} to find with first argument as :#{method}" do
122
- TestClass.should_receive(:find).with(method.to_sym)
123
- TestClass.send(method)
120
+ it "should call find with :all" do
121
+ TestClass.should_receive(:do_find).with(:all, anything)
122
+ TestClass.all
124
123
  end
125
124
 
126
- it "should delegate #{method}'s call to find with it's args as second argument" do
125
+ it "should delegate all's call to find with it's args as second argument" do
127
126
  options = {:foo => :bar}
128
- TestClass.should_receive(:find).with(anything, options)
129
- TestClass.send(method, options)
127
+ TestClass.should_receive(:do_find).with(anything, options)
128
+ TestClass.all options
129
+ end
130
+ end
131
+
132
+ describe "first" do
133
+ it "should respond to first" do
134
+ TestClass.should respond_to :first
135
+ end
136
+
137
+ it "should call find with :first" do
138
+ TestClass.should_receive(:do_find).with(:all, {:limit => 1}).and_return([])
139
+ TestClass.first
140
+ end
141
+
142
+ it "should delegate first's call to find with it's args as second argument" do
143
+ options = {:foo => :bar}
144
+ TestClass.should_receive(:do_find).with(anything, hash_including(options)).and_return([])
145
+ TestClass.first options
130
146
  end
131
147
  end
132
148
 
@@ -167,6 +183,19 @@ describe "finders" do
167
183
  all.should include @person, @bob
168
184
  all.length.should == 2
169
185
  end
186
+
187
+ it "should find all persons, even if it is more than 10" do
188
+ 15.times { |i| Person.create! :id => "id-#{i}", :name => "Going to die :-(", :age => i + 20 }
189
+ Person.all.length.should > 10
190
+ end
191
+
192
+ it "should raise error if not all requested records was found" do
193
+ lambda { Person.find(["ID1", "not exists"]) }.should raise_error MassiveRecord::ORM::RecordNotFound
194
+ end
195
+
196
+ it "should return what it finds if asked to" do
197
+ lambda { Person.find(["ID1", "not exists"], :skip_expected_result_check => true) }.should_not raise_error MassiveRecord::ORM::RecordNotFound
198
+ end
170
199
  end
171
200
 
172
201
  describe "#find_in_batches" do
@@ -183,6 +212,20 @@ describe "finders" do
183
212
  end
184
213
  group_number.should == @table_size / 3
185
214
  end
215
+
216
+ it "should not do a thing if table does not exist" do
217
+ Person.table.should_receive(:exists?).and_return false
218
+
219
+ counter = 0
220
+
221
+ Person.find_in_batches(:batch_size => 3) do |rows|
222
+ rows.each do |row|
223
+ counter += 1
224
+ end
225
+ end
226
+
227
+ counter.should == 0
228
+ end
186
229
 
187
230
  it "should iterate through a collection of rows using a batch process" do
188
231
  rows_number = 0
@@ -76,8 +76,9 @@ describe "persistence" do
76
76
  @person.reload.should == @person
77
77
  end
78
78
 
79
- it "should raise error on new record" do
80
- lambda { Person.new.reload }.should raise_error MassiveRecord::ORM::RecordNotFound
79
+ it "should not do anything on reload when record is not persisted" do
80
+ Person.should_not_receive :find
81
+ Person.new.reload
81
82
  end
82
83
  end
83
84
 
@@ -104,8 +105,8 @@ describe "persistence" do
104
105
  end
105
106
 
106
107
  it "should include the 'pts' field in the database which has 'points' as an alias" do
107
- @person.send(:attributes_to_row_values_hash)["info"].keys.should include("pts")
108
- @person.send(:attributes_to_row_values_hash)["info"].keys.should_not include("points")
108
+ @person.send(:attributes_to_row_values_hash)["base"].keys.should include("pts")
109
+ @person.send(:attributes_to_row_values_hash)["base"].keys.should_not include("points")
109
110
  end
110
111
  end
111
112
 
@@ -181,6 +182,9 @@ describe "persistence" do
181
182
  column_family :bar do
182
183
  field :foo
183
184
  end
185
+
186
+ column_family :empty_family do
187
+ end
184
188
  end
185
189
 
186
190
  @new_instance = @new_class.new :id => "id_of_foo", :foo => "bar"
@@ -202,7 +206,7 @@ describe "persistence" do
202
206
 
203
207
  it "should create correct column families" do
204
208
  @new_instance.save
205
- @new_class.table.fetch_column_families.collect(&:name).should == ["bar"]
209
+ @new_class.table.fetch_column_families.collect(&:name).should include "bar", "empty_family"
206
210
  end
207
211
 
208
212
  it "should store the new instance" do
@@ -343,6 +347,11 @@ describe "persistence" do
343
347
  @person.should be_destroyed
344
348
  Person.all.length.should == 0
345
349
  end
350
+
351
+ it "should be able to call destroy on new records" do
352
+ person = Person.new
353
+ person.destroy
354
+ end
346
355
 
347
356
  describe "#destroy_all" do
348
357
  it "should remove all when calling remove_all" do
@@ -354,6 +363,12 @@ describe "persistence" do
354
363
  it "should return an array of all removed objects" do
355
364
  Person.destroy_all.should == [@person]
356
365
  end
366
+
367
+ it "should destroy all even if it is above 10 rows (obviously)" do
368
+ 15.times { |i| Person.create! :id => "id-#{i}", :name => "Going to die :-(", :age => i + 20 }
369
+ Person.destroy_all
370
+ Person.all.length.should == 0
371
+ end
357
372
  end
358
373
  end
359
374
  end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'orm/models/friend'
3
+ require 'orm/models/best_friend'
4
+
5
+ describe "Single table inheritance" do
6
+ include SetUpHbaseConnectionBeforeAll
7
+ include SetTableNamesToTestTable
8
+
9
+ [Friend, BestFriend, BestFriend::SuperBestFriend].each do |klass|
10
+ describe klass do
11
+ let(:subject) { klass.new(:id => "ID1", :name => "Person1", :email => "one@person.com", :age => 11, :points => 111, :status => true) }
12
+
13
+ its(:type) { should == klass.to_s }
14
+
15
+ it "should instantiate correct class when reading from database" do
16
+ subject.save!
17
+ Person.find(subject.id).should == subject
18
+ end
19
+ end
20
+ end
21
+
22
+ it "should not set type if record being saved is base class" do
23
+ person = Person.new :id => "ID1", :name => "Person1", :email => "one@person.com", :age => 11, :points => 111, :status => true
24
+ person.type.should be_nil
25
+ end
26
+ end
@@ -52,7 +52,7 @@ describe "Person which is a table" do
52
52
  end
53
53
 
54
54
  it "should keep different column families per sub class" do
55
- Person.column_families.collect(&:name).should == ["info"]
55
+ Person.column_families.collect(&:name).should include "info", "base"
56
56
  TestClass.column_families.collect(&:name).should == ["test_family"]
57
57
  end
58
58
 
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'orm/models/person'
3
- require 'orm/models/person_with_timestamps'
3
+ require 'orm/models/person_with_timestamp'
4
4
 
5
5
  describe "timestamps" do
6
6
  include CreatePersonBeforeEach
@@ -56,11 +56,11 @@ describe "timestamps" do
56
56
 
57
57
  describe "#created_at" do
58
58
  before do
59
- @person_with_timestamps = PersonWithTimestamps.create! :name => "John Doe", :email => "john@base.com", :age => "20"
59
+ @person_with_timestamp = PersonWithTimestamp.create! :name => "John Doe", :email => "john@base.com", :age => "20"
60
60
  end
61
61
 
62
62
  it "should have created at" do
63
- @person_with_timestamps.should be_set_created_at_on_create
63
+ @person_with_timestamp.should be_set_created_at_on_create
64
64
  end
65
65
 
66
66
  it "should not have created at on create if model does not have created at" do
@@ -68,13 +68,13 @@ describe "timestamps" do
68
68
  end
69
69
 
70
70
  it "should have updated at equal to nil on new records" do
71
- PersonWithTimestamps.new.created_at.should be_nil
71
+ PersonWithTimestamp.new.created_at.should be_nil
72
72
  end
73
73
 
74
74
  it "should not be possible to set updated at" do
75
- lambda { @person_with_timestamps.created_at = Time.now }.should raise_error MassiveRecord::ORM::CantBeManuallyAssigned
76
- lambda { @person_with_timestamps['created_at'] = Time.now }.should raise_error MassiveRecord::ORM::CantBeManuallyAssigned
77
- lambda { @person_with_timestamps.write_attribute(:created_at, Time.now) }.should raise_error MassiveRecord::ORM::CantBeManuallyAssigned
75
+ lambda { @person_with_timestamp.created_at = Time.now }.should raise_error MassiveRecord::ORM::CantBeManuallyAssigned
76
+ lambda { @person_with_timestamp['created_at'] = Time.now }.should raise_error MassiveRecord::ORM::CantBeManuallyAssigned
77
+ lambda { @person_with_timestamp.write_attribute(:created_at, Time.now) }.should raise_error MassiveRecord::ORM::CantBeManuallyAssigned
78
78
  end
79
79
 
80
80
  it "should not raise cant-set-error if object has no timestamps" do
@@ -82,24 +82,24 @@ describe "timestamps" do
82
82
  end
83
83
 
84
84
  it "should have created_at on a persisted record" do
85
- @person_with_timestamps.created_at.should be_a_kind_of Time
85
+ @person_with_timestamp.created_at.should be_a_kind_of Time
86
86
  end
87
87
 
88
88
  it "should not alter created at on update" do
89
- created_at_was = @person_with_timestamps.created_at
89
+ created_at_was = @person_with_timestamp.created_at
90
90
 
91
91
  sleep(1)
92
92
 
93
- @person_with_timestamps.update_attribute :name, @person_with_timestamps.name + "NEW"
94
- @person_with_timestamps.created_at.should == created_at_was
93
+ @person_with_timestamp.update_attribute :name, @person_with_timestamp.name + "NEW"
94
+ @person_with_timestamp.created_at.should == created_at_was
95
95
  end
96
96
 
97
97
  it "should be included in the list of known_attribute_names_for_inspect" do
98
- @person_with_timestamps.send(:known_attribute_names_for_inspect).should include 'created_at'
98
+ @person_with_timestamp.send(:known_attribute_names_for_inspect).should include 'created_at'
99
99
  end
100
100
 
101
101
  it "should include created_at in inspect" do
102
- @person_with_timestamps.inspect.should include(%q{created_at:})
102
+ @person_with_timestamp.inspect.should include(%q{created_at:})
103
103
  end
104
104
 
105
105
  it "should not include created_at if object does not have it" do
@@ -107,11 +107,11 @@ describe "timestamps" do
107
107
  end
108
108
 
109
109
  it "should raise error if created_at is not time" do
110
- PersonWithTimestamps.attributes_schema['created_at'].type = :string
110
+ PersonWithTimestamp.attributes_schema['created_at'].type = :string
111
111
 
112
- lambda { PersonWithTimestamps.create! }.should raise_error "created_at must be of type time"
112
+ lambda { PersonWithTimestamp.create! }.should raise_error "created_at must be of type time"
113
113
 
114
- PersonWithTimestamps.attributes_schema['created_at'].type = :time
114
+ PersonWithTimestamp.attributes_schema['created_at'].type = :time
115
115
  end
116
116
  end
117
117
  end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe MassiveRecord::ORM::Coders::Chained do
4
+ describe "initialize" do
5
+ it "should be able to assign coder to load- and dump with" do
6
+ coders = MassiveRecord::ORM::Coders::JSON.new
7
+ coder = MassiveRecord::ORM::Coders::Chained.new(coders)
8
+ coder.loaders.should include coders
9
+ coder.dumpers.should include coders
10
+ end
11
+
12
+ it "should be able to assign array of coders to load- and dump with" do
13
+ coders = [MassiveRecord::ORM::Coders::JSON.new, MassiveRecord::ORM::Coders::YAML.new]
14
+ coder = MassiveRecord::ORM::Coders::Chained.new(coders)
15
+ coder.loaders.should include *coders
16
+ coder.dumpers.should include *coders
17
+ end
18
+
19
+ it "should be possible to assign load_with explicitly" do
20
+ coders = MassiveRecord::ORM::Coders::JSON.new
21
+ load_with = MassiveRecord::ORM::Coders::YAML.new
22
+ coder = MassiveRecord::ORM::Coders::Chained.new(coders, :load_with => load_with)
23
+ coder.loaders.should include load_with
24
+ coder.dumpers.should include coders
25
+ end
26
+
27
+ it "should be possible to assign dump_with explicitly" do
28
+ coders = MassiveRecord::ORM::Coders::JSON.new
29
+ dump_with = MassiveRecord::ORM::Coders::YAML.new
30
+ coder = MassiveRecord::ORM::Coders::Chained.new(coders, :dump_with => dump_with)
31
+ coder.loaders.should include coders
32
+ coder.dumpers.should include dump_with
33
+ end
34
+ end
35
+
36
+
37
+
38
+ describe "one coder in chain" do
39
+ let(:subject) { MassiveRecord::ORM::Coders::Chained.new(MassiveRecord::ORM::Coders::JSON.new) }
40
+ let(:code_with) { lambda { |value| ActiveSupport::JSON.encode(value) } }
41
+
42
+ it_should_behave_like "an orm coder"
43
+ end
44
+
45
+
46
+
47
+ describe "two loaders in chain" do
48
+ let(:subject) do
49
+ MassiveRecord::ORM::Coders::Chained.new({
50
+ :load_with => [MassiveRecord::ORM::Coders::JSON.new, MassiveRecord::ORM::Coders::YAML.new],
51
+ :dump_with => MassiveRecord::ORM::Coders::YAML.new
52
+ })
53
+ end
54
+
55
+ let(:code_with) { lambda { |value| YAML.dump(value) } }
56
+
57
+ it_should_behave_like "an orm coder"
58
+
59
+ it "it should try the next loader in the line if the first one fails" do
60
+ data = {:foo => {'sdf' => "wef"}} # Will make the json encoder fail when YAML serialized
61
+ subject.load(YAML.dump(data)).should == data
62
+ end
63
+
64
+ it "should raise ParseError if all fails" do
65
+ lambda { subject.load("{{}]") }.should raise_error MassiveRecord::ORM::Coders::ParseError
66
+ end
67
+
68
+ it "should raise EncodeError if all fails" do
69
+ subject.dumpers.first.should_receive(:dump).and_raise(StandardError)
70
+ lambda { subject.dump("unable to dump") }.should raise_error MassiveRecord::ORM::Coders::EncodeError
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe MassiveRecord::ORM::Coders::JSON do
4
+ let(:code_with) { lambda { |value| ActiveSupport::JSON.encode(value) } }
5
+ it_should_behave_like "an orm coder"
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe MassiveRecord::ORM::Coders::YAML do
4
+ let(:code_with) { lambda { |value| value.to_yaml } }
5
+ it_should_behave_like "an orm coder"
6
+ end
@@ -0,0 +1,7 @@
1
+ require 'orm/models/friend'
2
+
3
+ class BestFriend < Friend
4
+ class SuperBestFriend < BestFriend
5
+ end
6
+ end
7
+
@@ -0,0 +1,4 @@
1
+ require 'orm/models/person'
2
+
3
+ class Friend < Person
4
+ end
@@ -1,15 +1,29 @@
1
1
  class Person < MassiveRecord::ORM::Table
2
- validates_presence_of :name, :age
3
- validates_numericality_of :age, :greater_than_or_equal_to => 0
4
- validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :allow_blank => true
5
-
6
2
  column_family :info do
7
3
  field :name
8
4
  field :email
9
5
  field :age, :integer
10
- field :points, :integer, :default => 1, :column => :pts
11
6
  field :date_of_birth, :date
12
- field :status, :boolean, :default => false
13
7
  field :addresses, :hash, :default => {}
8
+ field :type
9
+ end
10
+
11
+ column_family :base do
12
+ field :points, :integer, :default => 1, :column => :pts
13
+ field :status, :boolean, :default => false
14
+ end
15
+
16
+
17
+ references_one :boss, :class_name => "PersonWithTimestamp", :store_in => :info
18
+ references_many :test_classes, :store_in => :info
19
+ references_many :friends, :class_name => "Person", :records_starts_from => :friends_records_starts_from_id
20
+
21
+ validates_presence_of :name, :age
22
+ validates_numericality_of :age, :greater_than_or_equal_to => 0
23
+ validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :allow_blank => true
24
+
25
+
26
+ def friends_records_starts_from_id
27
+ id+'-'
14
28
  end
15
29
  end
@@ -1,4 +1,4 @@
1
- class PersonWithTimestamps < MassiveRecord::ORM::Table
1
+ class PersonWithTimestamp < MassiveRecord::ORM::Table
2
2
  column_family :info do
3
3
  field :name
4
4
  field :email