sam-dm-core 0.9.10 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/.gitignore +18 -0
  2. data/History.txt +10 -0
  3. data/MIT-LICENSE +1 -1
  4. data/Rakefile +4 -4
  5. data/dm-core.gemspec +40 -0
  6. data/lib/dm-core.rb +1 -1
  7. data/lib/dm-core/adapters/data_objects_adapter.rb +2 -2
  8. data/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
  9. data/lib/dm-core/adapters/mysql_adapter.rb +1 -1
  10. data/lib/dm-core/adapters/postgres_adapter.rb +1 -1
  11. data/lib/dm-core/adapters/sqlite3_adapter.rb +1 -1
  12. data/lib/dm-core/associations/many_to_one.rb +1 -1
  13. data/lib/dm-core/associations/one_to_many.rb +18 -18
  14. data/lib/dm-core/associations/relationship.rb +9 -3
  15. data/lib/dm-core/associations/relationship_chain.rb +1 -1
  16. data/lib/dm-core/collection.rb +3 -3
  17. data/lib/dm-core/model.rb +5 -4
  18. data/lib/dm-core/resource.rb +11 -5
  19. data/lib/dm-core/version.rb +1 -1
  20. data/script/all +3 -4
  21. data/spec/integration/association_spec.rb +18 -18
  22. data/spec/integration/association_through_spec.rb +4 -4
  23. data/spec/integration/associations/many_to_many_spec.rb +9 -9
  24. data/spec/integration/associations/many_to_one_spec.rb +1 -1
  25. data/spec/integration/associations/one_to_many_spec.rb +3 -3
  26. data/spec/integration/collection_spec.rb +2 -2
  27. data/spec/integration/dependency_queue_spec.rb +1 -1
  28. data/spec/integration/model_spec.rb +1 -1
  29. data/spec/integration/mysql_adapter_spec.rb +1 -1
  30. data/spec/integration/postgres_adapter_spec.rb +16 -16
  31. data/spec/integration/property_spec.rb +10 -6
  32. data/spec/integration/query_spec.rb +4 -4
  33. data/spec/integration/repository_spec.rb +1 -1
  34. data/spec/integration/sqlite3_adapter_spec.rb +7 -7
  35. data/spec/integration/sti_spec.rb +6 -6
  36. data/spec/integration/strategic_eager_loading_spec.rb +14 -11
  37. data/spec/integration/type_spec.rb +10 -6
  38. data/spec/lib/logging_helper.rb +11 -11
  39. data/spec/models/content.rb +16 -0
  40. data/spec/spec_helper.rb +8 -4
  41. data/spec/unit/adapters/data_objects_adapter_spec.rb +9 -5
  42. data/spec/unit/adapters/in_memory_adapter_spec.rb +98 -0
  43. data/spec/unit/adapters/postgres_adapter_spec.rb +5 -5
  44. data/spec/unit/associations/many_to_many_spec.rb +2 -2
  45. data/spec/unit/associations/many_to_one_spec.rb +3 -3
  46. data/spec/unit/associations/one_to_many_spec.rb +2 -2
  47. data/spec/unit/associations/relationship_spec.rb +6 -6
  48. data/spec/unit/associations_spec.rb +21 -21
  49. data/spec/unit/identity_map_spec.rb +3 -3
  50. data/spec/unit/is_spec.rb +7 -7
  51. data/spec/unit/property_spec.rb +7 -7
  52. data/spec/unit/resource_spec.rb +12 -12
  53. data/spec/unit/transaction_spec.rb +1 -1
  54. data/tasks/dm.rb +1 -1
  55. metadata +10 -5
@@ -25,7 +25,7 @@ if HAS_POSTGRES
25
25
  @adapter.stub!(:query).and_return([ 0 ])
26
26
 
27
27
  @original_method = @adapter.class.superclass.instance_method(:upgrade_model_storage)
28
- @adapter.class.superclass.send(:define_method, :upgrade_model_storage) {}
28
+ @adapter.class.superclass.send(:define_method, :upgrade_model_storage) { |repository, model| }
29
29
  end
30
30
 
31
31
  after do
@@ -49,7 +49,7 @@ if HAS_POSTGRES
49
49
 
50
50
  it 'should execute the superclass upgrade_model_storage' do
51
51
  rv = mock('inside super')
52
- @adapter.class.superclass.send(:define_method, :upgrade_model_storage) { rv }
52
+ @adapter.class.superclass.send(:define_method, :upgrade_model_storage) { |repository, model| rv }
53
53
  @adapter.upgrade_model_storage(@repository, @model).should == rv
54
54
  end
55
55
  end
@@ -91,7 +91,7 @@ if HAS_POSTGRES
91
91
 
92
92
  it 'should execute the superclass upgrade_model_storage' do
93
93
  rv = mock('inside super')
94
- @adapter.class.superclass.send(:define_method, :create_table_statement) { rv }
94
+ @adapter.class.superclass.send(:define_method, :create_table_statement) { |repository, model| rv }
95
95
  @adapter.create_table_statement(@repository, @model).should == rv
96
96
  end
97
97
  end
@@ -117,13 +117,13 @@ if HAS_POSTGRES
117
117
 
118
118
  it 'should not execute the superclass destroy_model_storage if the storage does not exist' do
119
119
  rv = mock('inside super')
120
- @adapter.class.superclass.send(:define_method, :destroy_model_storage) { rv }
120
+ @adapter.class.superclass.send(:define_method, :destroy_model_storage) { |repository, model| rv }
121
121
  @adapter.destroy_model_storage(@repository, @model).should_not == rv
122
122
  end
123
123
 
124
124
  it 'should execute the superclass destroy_model_storage if the storage exists' do
125
125
  rv = mock('inside super')
126
- @adapter.class.superclass.send(:define_method, :destroy_model_storage) { rv }
126
+ @adapter.class.superclass.send(:define_method, :destroy_model_storage) { |repository, model| rv }
127
127
  @adapter.stub!(:storage_exists?).and_return(true)
128
128
 
129
129
  @adapter.destroy_model_storage(@repository, @model).should == rv
@@ -6,7 +6,7 @@ describe DataMapper::Associations::ManyToMany do
6
6
 
7
7
  it 'should allow a declaration' do
8
8
  lambda do
9
- class Supplier
9
+ class ::Supplier
10
10
  has n, :manufacturers, :through => Resource
11
11
  end
12
12
  end.should_not raise_error
@@ -14,7 +14,7 @@ describe DataMapper::Associations::ManyToMany do
14
14
 
15
15
  it 'should handle models inside modules' do
16
16
  lambda do
17
- module Content
17
+ module ::Content
18
18
  class Dialect
19
19
  has n, :locales, :through => Resource, :class_name => "Language::Locale"
20
20
  end
@@ -6,7 +6,7 @@ describe DataMapper::Associations::ManyToOne do
6
6
 
7
7
  it 'should allow a declaration' do
8
8
  lambda do
9
- class Vehicle
9
+ class ::Vehicle
10
10
  belongs_to :manufacturer
11
11
  end
12
12
  end.should_not raise_error
@@ -102,7 +102,7 @@ describe DataMapper::Associations::ManyToOne::Proxy do
102
102
  end
103
103
 
104
104
  it 'should save the parent' do
105
- @relationship.should_receive(:with_repository).and_yield(@repository)
105
+ @relationship.should_receive(:with_repository).and_yield
106
106
  @parent.should_receive(:save).with(no_args)
107
107
  @association.save
108
108
  end
@@ -112,7 +112,7 @@ describe DataMapper::Associations::ManyToOne::Proxy do
112
112
  child_key.should_receive(:set).and_return(true)
113
113
  parent_key = mock("parent_key")
114
114
  parent_key.should_receive(:get).and_return(1)
115
- @relationship.should_receive(:with_repository).and_yield(@repository)
115
+ @relationship.should_receive(:with_repository).and_yield
116
116
  @relationship.should_receive(:child_key).and_return(child_key)
117
117
  @relationship.should_receive(:parent_key).and_return(parent_key)
118
118
  save_results = mock('save results')
@@ -85,11 +85,11 @@ describe DataMapper::Associations::OneToMany do
85
85
 
86
86
  describe 'proxy accessor' do
87
87
  before :all do
88
- class User
88
+ class ::User
89
89
  include DataMapper::Resource
90
90
  end
91
91
 
92
- class Order
92
+ class ::Order
93
93
  include DataMapper::Resource
94
94
  end
95
95
  end
@@ -8,8 +8,8 @@ describe DataMapper::Associations::Relationship do
8
8
  belongs_to = DataMapper::Associations::Relationship.new(
9
9
  :manufacturer,
10
10
  :mock,
11
- 'Vehicle',
12
- 'Manufacturer',
11
+ Vehicle,
12
+ Manufacturer,
13
13
  { :child_key => [ :manufacturer_id ] }
14
14
  )
15
15
 
@@ -23,8 +23,8 @@ describe DataMapper::Associations::Relationship do
23
23
  belongs_to = DataMapper::Associations::Relationship.new(
24
24
  :manufacturer,
25
25
  :mock,
26
- 'Vehicle',
27
- 'Manufacturer',
26
+ Vehicle,
27
+ Manufacturer,
28
28
  { :child_key => [ :manufacturer_id ], :parent_key => [ :id ] }
29
29
  )
30
30
 
@@ -44,8 +44,8 @@ describe DataMapper::Associations::Relationship do
44
44
  has_many = DataMapper::Associations::Relationship.new(
45
45
  :models,
46
46
  :mock,
47
- 'Vehicle',
48
- 'Manufacturer',
47
+ Vehicle,
48
+ Manufacturer,
49
49
  { :child_key => [:model_id] }
50
50
  )
51
51
 
@@ -13,7 +13,7 @@ describe "DataMapper::Associations" do
13
13
 
14
14
  describe "#many_to_one_relationships" do
15
15
  before :all do
16
- module MTORelationships
16
+ module ::MTORelationships
17
17
  class A
18
18
  include DataMapper::Resource
19
19
  def self.default_repository_name
@@ -46,11 +46,11 @@ describe "DataMapper::Associations" do
46
46
  end
47
47
 
48
48
  describe ".relationships" do
49
- class B
49
+ class ::B
50
50
  include DataMapper::Resource
51
51
  end
52
52
 
53
- class C
53
+ class ::C
54
54
  include DataMapper::Resource
55
55
 
56
56
  repository(:mock) do
@@ -58,15 +58,15 @@ describe "DataMapper::Associations" do
58
58
  end
59
59
  end
60
60
 
61
- class D
61
+ class ::D
62
62
  include DataMapper::Resource
63
63
  has 1, :b
64
64
  end
65
65
 
66
- class E < D
66
+ class ::E < D
67
67
  end
68
68
 
69
- class F < D
69
+ class ::F < D
70
70
  has 1, :a
71
71
  end
72
72
 
@@ -92,7 +92,7 @@ describe "DataMapper::Associations" do
92
92
 
93
93
  it "should allow a declaration" do
94
94
  lambda do
95
- class Manufacturer
95
+ class ::Manufacturer
96
96
  has 1, :halo_car
97
97
  end
98
98
  end.should_not raise_error
@@ -100,7 +100,7 @@ describe "DataMapper::Associations" do
100
100
 
101
101
  it "should not allow a constraint that is not an Integer, Range or Infinity" do
102
102
  lambda do
103
- class Manufacturer
103
+ class ::Manufacturer
104
104
  has '1', :halo_car
105
105
  end
106
106
  end.should raise_error(ArgumentError)
@@ -108,7 +108,7 @@ describe "DataMapper::Associations" do
108
108
 
109
109
  it "should not allow a constraint where the min is larger than the max" do
110
110
  lambda do
111
- class Manufacturer
111
+ class ::Manufacturer
112
112
  has 1..0, :halo_car
113
113
  end
114
114
  end.should raise_error(ArgumentError)
@@ -119,7 +119,7 @@ describe "DataMapper::Associations" do
119
119
  with(:vehicles, Manufacturer, { :min => 1, :max => 2 }).
120
120
  and_return(@relationship)
121
121
 
122
- class Manufacturer
122
+ class ::Manufacturer
123
123
  has(1..2, :vehicles, :min => 5, :max => 10).should == mock_relationship
124
124
  end
125
125
  end
@@ -130,7 +130,7 @@ describe "DataMapper::Associations" do
130
130
  with(:halo_car, Manufacturer, { :min => 1, :max => 1 }).
131
131
  and_return(@relationship)
132
132
 
133
- class Manufacturer
133
+ class ::Manufacturer
134
134
  has(1, :halo_car).should == mock_relationship
135
135
  end
136
136
  end
@@ -140,7 +140,7 @@ describe "DataMapper::Associations" do
140
140
  with(:halo_car, Manufacturer, { :min => 0, :max => 1 }).
141
141
  and_return(@relationship)
142
142
 
143
- class Manufacturer
143
+ class ::Manufacturer
144
144
  has(0..1, :halo_car).should == mock_relationship
145
145
  end
146
146
  end
@@ -150,7 +150,7 @@ describe "DataMapper::Associations" do
150
150
  with(:halo_car, Manufacturer, { :min => 1, :max => 1, :class_name => 'Car' }).
151
151
  and_return(@relationship)
152
152
 
153
- class Manufacturer
153
+ class ::Manufacturer
154
154
  has(1, :halo_car, :class_name => 'Car').should == mock_relationship
155
155
  end
156
156
  end
@@ -162,7 +162,7 @@ describe "DataMapper::Associations" do
162
162
  with(:vehicles, Manufacturer, { :min => 0, :max => @n }).
163
163
  and_return(@relationship)
164
164
 
165
- class Manufacturer
165
+ class ::Manufacturer
166
166
  has(n, :vehicles).should == mock_relationship
167
167
  end
168
168
  end
@@ -172,7 +172,7 @@ describe "DataMapper::Associations" do
172
172
  with(:vehicles, Manufacturer, { :min => 4, :max => 4 }).
173
173
  and_return(@relationship)
174
174
 
175
- class Manufacturer
175
+ class ::Manufacturer
176
176
  has(4, :vehicles).should == mock_relationship
177
177
  end
178
178
  end
@@ -182,7 +182,7 @@ describe "DataMapper::Associations" do
182
182
  with(:vehicles, Manufacturer, { :min => 2, :max => 4 }).
183
183
  and_return(@relationship)
184
184
 
185
- class Manufacturer
185
+ class ::Manufacturer
186
186
  has(2..4, :vehicles).should == mock_relationship
187
187
  end
188
188
  end
@@ -192,7 +192,7 @@ describe "DataMapper::Associations" do
192
192
  with(:vehicles, Manufacturer, { :min => 1, :max => @n, :class_name => 'Car' }).
193
193
  and_return(@relationship)
194
194
 
195
- class Manufacturer
195
+ class ::Manufacturer
196
196
  has(1..n, :vehicles, :class_name => 'Car').should == mock_relationship
197
197
  end
198
198
  end
@@ -200,7 +200,7 @@ describe "DataMapper::Associations" do
200
200
  # do not remove or change this spec.
201
201
  it "should raise an exception when n..n is used for the cardinality" do
202
202
  lambda do
203
- class Manufacturer
203
+ class ::Manufacturer
204
204
  has n..n, :subsidiaries, :class_name => 'Manufacturer'
205
205
  end
206
206
  end.should raise_error(ArgumentError)
@@ -211,7 +211,7 @@ describe "DataMapper::Associations" do
211
211
  with(:suppliers, Vehicle, { :min => 0, :max => @n, :through => :manufacturers }).
212
212
  and_return(@relationship)
213
213
 
214
- class Vehicle
214
+ class ::Vehicle
215
215
  has(n, :suppliers, :through => :manufacturers).should == mock_relationship
216
216
  end
217
217
  end
@@ -224,7 +224,7 @@ describe "DataMapper::Associations" do
224
224
  with(:vehicle, Manufacturer, {}).
225
225
  and_return(@relationship)
226
226
 
227
- class Manufacturer
227
+ class ::Manufacturer
228
228
  belongs_to(:vehicle).should == mock_relationship
229
229
  end
230
230
  end
@@ -234,7 +234,7 @@ describe "DataMapper::Associations" do
234
234
  with(:vehicle, Manufacturer, { :class_name => 'Car' }).
235
235
  and_return(@relationship)
236
236
 
237
- class Manufacturer
237
+ class ::Manufacturer
238
238
  belongs_to(:vehicle, :class_name => 'Car').should == mock_relationship
239
239
  end
240
240
  end
@@ -2,18 +2,18 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
2
 
3
3
  describe "DataMapper::IdentityMap" do
4
4
  before(:all) do
5
- class Cow
5
+ class ::Cow
6
6
  include DataMapper::Resource
7
7
  property :id, Integer, :key => true
8
8
  property :name, String
9
9
  end
10
10
 
11
- class Chicken
11
+ class ::Chicken
12
12
  include DataMapper::Resource
13
13
  property :name, String
14
14
  end
15
15
 
16
- class Pig
16
+ class ::Pig
17
17
  include DataMapper::Resource
18
18
  property :id, Integer, :key => true
19
19
  property :composite, Integer, :key => true
@@ -3,7 +3,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
3
3
  describe "DataMapper::Is" do
4
4
  describe ".is" do
5
5
 
6
- module DataMapper
6
+ module ::DataMapper
7
7
 
8
8
  module Is
9
9
  module Example
@@ -32,17 +32,17 @@ describe "DataMapper::Is" do
32
32
  end # module Model
33
33
  end # module DataMapper
34
34
 
35
- class House
35
+ class ::House
36
36
  include DataMapper::Resource
37
37
  end
38
38
 
39
- class Cabin
39
+ class ::Cabin
40
40
  include DataMapper::Resource
41
41
  end
42
42
 
43
43
  it "should raise error unless it finds the plugin" do
44
44
  lambda do
45
- class House
45
+ class ::House
46
46
  is :no_plugin_by_this_name
47
47
  end
48
48
  end.should raise_error(DataMapper::PluginNotFoundError)
@@ -50,14 +50,14 @@ describe "DataMapper::Is" do
50
50
 
51
51
  it "should call plugin is_* method" do
52
52
  lambda do
53
- class House
53
+ class ::House
54
54
  is :example
55
55
  end
56
56
  end.should_not raise_error
57
57
  end
58
58
 
59
59
  it "should pass through arguments to plugin is_* method" do
60
- class House
60
+ class ::House
61
61
  is :example ,:option1 => :ping, :option2 => :pong
62
62
  end
63
63
 
@@ -68,7 +68,7 @@ describe "DataMapper::Is" do
68
68
  it "should not add class_methods before the plugin is activated" do
69
69
  Cabin.respond_to?(:example_class_method).should be_false
70
70
 
71
- class Cabin
71
+ class ::Cabin
72
72
  is :example
73
73
  end
74
74
 
@@ -3,14 +3,14 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
3
3
  describe DataMapper::Property do
4
4
  before :each do
5
5
  Object.send(:remove_const, :Zoo) if defined?(Zoo)
6
- class Zoo
6
+ class ::Zoo
7
7
  include DataMapper::Resource
8
8
 
9
9
  property :id, DataMapper::Types::Serial
10
10
  end
11
11
 
12
12
  Object.send(:remove_const, :Name) if defined?(Name)
13
- class Name < DataMapper::Type
13
+ class ::Name < DataMapper::Type
14
14
  primitive String
15
15
  track :hash
16
16
 
@@ -28,7 +28,7 @@ describe DataMapper::Property do
28
28
  end
29
29
 
30
30
  Object.send(:remove_const, :Tomato) if defined?(Tomato)
31
- class Tomato
31
+ class ::Tomato
32
32
  include DataMapper::Resource
33
33
  end
34
34
  end
@@ -286,7 +286,7 @@ describe DataMapper::Property do
286
286
 
287
287
  it "should not have key that is lazy" do
288
288
  Zoo.class_eval do
289
- property :id, DataMapper::Types::Text, :key => true
289
+ property :id, String, :lazy => true, :key => true
290
290
  property :name, String, :lazy => true
291
291
  end
292
292
  Zoo.auto_migrate!
@@ -429,8 +429,8 @@ describe DataMapper::Property do
429
429
  Tomato.class_eval <<-RUBY
430
430
  property :botanical_name, String, #{input.inspect}
431
431
  RUBY
432
- Tomato.send("#{output[0]}_instance_methods").should include("botanical_name")
433
- Tomato.send("#{output[1]}_instance_methods").should include("botanical_name=")
432
+ Tomato.send("#{output[0]}_instance_methods").map { |m| m.to_s }.should include("botanical_name")
433
+ Tomato.send("#{output[1]}_instance_methods").map { |m| m.to_s }.should include("botanical_name=")
434
434
  end
435
435
  end
436
436
 
@@ -466,7 +466,7 @@ describe DataMapper::Property do
466
466
  # end
467
467
 
468
468
  it "should append ? to TrueClass property reader methods" do
469
- class Potato
469
+ class ::Potato
470
470
  include DataMapper::Resource
471
471
  property :id, Integer, :key => true
472
472
  property :fresh, TrueClass
@@ -60,7 +60,7 @@ end
60
60
  describe DataMapper::Resource do
61
61
  before(:each) do
62
62
  Object.send(:remove_const, :Planet) if defined?(Planet)
63
- class Planet
63
+ class ::Planet
64
64
  include DataMapper::Resource
65
65
 
66
66
  storage_names[:legacy] = "dying_planets"
@@ -86,7 +86,7 @@ describe DataMapper::Resource do
86
86
  end
87
87
 
88
88
  Object.send(:remove_const, :Phone) if defined?(Phone)
89
- class Phone
89
+ class ::Phone
90
90
  include DataMapper::Resource
91
91
 
92
92
  property :name, String, :key => true
@@ -94,7 +94,7 @@ describe DataMapper::Resource do
94
94
  end
95
95
 
96
96
  Object.send(:remove_const, :Fruit) if defined?(Fruit)
97
- class Fruit
97
+ class ::Fruit
98
98
  include DataMapper::Resource
99
99
 
100
100
  property :id, Integer, :key => true
@@ -102,7 +102,7 @@ describe DataMapper::Resource do
102
102
  end
103
103
 
104
104
  Object.send(:remove_const, :Grain) if defined?(Grain)
105
- class Grain
105
+ class ::Grain
106
106
  include DataMapper::Resource
107
107
 
108
108
  property :id, Serial
@@ -110,7 +110,7 @@ describe DataMapper::Resource do
110
110
  end
111
111
 
112
112
  Object.send(:remove_const, :Vegetable) if defined?(Vegetable)
113
- class Vegetable
113
+ class ::Vegetable
114
114
  include DataMapper::Resource
115
115
 
116
116
  property :id, Serial
@@ -118,12 +118,12 @@ describe DataMapper::Resource do
118
118
  end
119
119
 
120
120
  Object.send(:remove_const, :Banana) if defined?(Banana)
121
- class Banana < Fruit
121
+ class ::Banana < Fruit
122
122
  property :type, Discriminator
123
123
  end
124
124
 
125
125
  Object.send(:remove_const, :Cyclist) if defined?(Cyclist)
126
- class Cyclist
126
+ class ::Cyclist
127
127
  include DataMapper::Resource
128
128
  property :id, Serial
129
129
  property :victories, Integer
@@ -568,7 +568,7 @@ describe DataMapper::Resource do
568
568
 
569
569
  describe "inheritance" do
570
570
  before(:all) do
571
- class Media
571
+ class ::Media
572
572
  include DataMapper::Resource
573
573
 
574
574
  storage_names[:default] = 'media'
@@ -577,7 +577,7 @@ describe DataMapper::Resource do
577
577
  property :name, String, :key => true
578
578
  end
579
579
 
580
- class NewsPaper < Media
580
+ class ::NewsPaper < Media
581
581
 
582
582
  storage_names[:east_coast] = 'mother'
583
583
 
@@ -600,7 +600,7 @@ describe DataMapper::Resource do
600
600
 
601
601
  describe "Single-table Inheritance" do
602
602
  before(:all) do
603
- class Plant
603
+ class ::Plant
604
604
  include DataMapper::Resource
605
605
 
606
606
  property :id, Integer, :key => true
@@ -615,13 +615,13 @@ describe DataMapper::Resource do
615
615
  end
616
616
  end
617
617
 
618
- class HousePlant < Plant
618
+ class ::HousePlant < Plant
619
619
  def calculate(int)
620
620
  int ** 3
621
621
  end
622
622
  end
623
623
 
624
- class PoisonIvy < Plant
624
+ class ::PoisonIvy < Plant
625
625
  def length=(len)
626
626
  attribute_set(:length, len - 1)
627
627
  end