dbview_cti 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.1.3 (3/11/2013)
2
+
3
+ * Fixed validation issue
4
+ * Improved handling of associations in new (not yet persisted) objects
5
+
1
6
  ## 0.1.2 (27/10/2013)
2
7
 
3
8
  * Fundamental change to how associations are handled in order to solve problems with build
@@ -58,10 +58,12 @@ module DBViewCTI
58
58
 
59
59
  # for associations:
60
60
  alias_method_chain :association, :cti
61
- validate :cti_validate_associations
62
-
63
61
  # save callbacks (necessary for saving associations)
64
62
  after_save :cti_save_associations
63
+
64
+ # validations
65
+ validate :cti_validate_associations
66
+ attr_accessor :cti_disable_validations
65
67
  end
66
68
 
67
69
  def destroy_with_cti
@@ -2,7 +2,7 @@ require 'delegate'
2
2
 
3
3
  module DBViewCTI
4
4
  module Model
5
-
5
+
6
6
  class ModelDelegator < SimpleDelegator
7
7
 
8
8
  attr_reader :cti_target_class
@@ -11,9 +11,10 @@ module DBViewCTI
11
11
  @cti_object = object
12
12
  @cti_converted_object = object.convert_to(target_class)
13
13
  if !@cti_converted_object
14
- @cti_converted_object = object.becomes(target_class.constantize)
14
+ @cti_converted_object = target_class.constantize.new
15
15
  @cti_is_new = true
16
16
  end
17
+ disable_validations
17
18
  @cti_target_class = target_class
18
19
  super( @cti_converted_object )
19
20
  end
@@ -24,24 +25,60 @@ module DBViewCTI
24
25
 
25
26
  def save(*args, &block)
26
27
  return super unless cti_is_new?
27
- # special case for new objects, we need som hackish id-juggling
28
- old_id = @cti_object.id
28
+ # special case for new objects, we need to manually set the id and trick the object
29
+ # to think it was already persisted, so we get an update instead of an insert
29
30
  new_id = @cti_object.convert_to( @cti_target_class ).id
30
- # since @cti_converted_object was created using 'becomes', @cti_object.id changes
31
- # as well in the following statement. So we saved it in old_id and restore it after the
32
- # call to save (i.e. super)
33
- @cti_object.reload # only needed in rails 4
34
31
  self.id = new_id
35
- self.created_at = @cti_object.created_at # only needed in rails 4
36
- self.updated_at = @cti_object.updated_at # only needed in rails 4
32
+ force_persisted_state
33
+ self.created_at = @cti_object.created_at
34
+ self.updated_at = @cti_object.updated_at
37
35
  retval = !!super
38
- @cti_is_new = false
39
- @cti_object.id = old_id
36
+ # throw away just saved object and convert from scratch
40
37
  @cti_converted_object = @cti_object.convert_to( @cti_target_class )
38
+ disable_validations
41
39
  __setobj__(@cti_converted_object)
42
- retval
40
+ return retval
43
41
  end
44
42
 
43
+ private
44
+
45
+ module DisableValidator
46
+ def validate_each(record, *args)
47
+ return if record.respond_to?(:cti_disable_validations) && record.cti_disable_validations
48
+ super
49
+ end
50
+
51
+ if Rails::VERSION::MAJOR == 3
52
+ def validate(record, *args)
53
+ return if record.respond_to?(:cti_disable_validations) && record.cti_disable_validations
54
+ super
55
+ end
56
+ end
57
+ end
58
+
59
+ def disable_validations(object = nil)
60
+ object ||= @cti_converted_object
61
+ object.cti_disable_validations = true
62
+ object._validators.values.flatten.each do |validator|
63
+ validator.extend( DisableValidator )
64
+ end
65
+ end
66
+
67
+ module ForcePersistedState
68
+ def persisted?
69
+ true
70
+ end
71
+
72
+ def new_record?
73
+ false
74
+ end
75
+ end
76
+
77
+ def force_persisted_state(object = nil)
78
+ object ||= @cti_converted_object
79
+ object.extend( ForcePersistedState )
80
+ end
81
+
45
82
  end
46
83
 
47
84
  end
@@ -1,3 +1,3 @@
1
1
  module DBViewCTI
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -1,4 +1,6 @@
1
1
  class Vehicle < ActiveRecord::Base
2
2
  attr_accessible :name, :mass unless Rails::VERSION::MAJOR > 3
3
3
  cti_base_class
4
+
5
+ validates :name, :presence => true
4
6
  end
@@ -23,7 +23,7 @@ describe SpaceShuttle do
23
23
  before :each do
24
24
  # create dummy space ships to make sure the shuttle we'll create has a different database id than
25
25
  # its associated spaceship
26
- (1..2).map { SpaceShip.create }
26
+ (1..2).map { SpaceShip.create(:name => 'test') }
27
27
  @shuttle = SpaceShuttle.create(:name => 'Discovery', :reliability => 100)
28
28
  @shuttle.id.should_not eq @shuttle.convert_to(:space_ship).id
29
29
  end
@@ -365,7 +365,7 @@ describe SpaceShuttle do
365
365
  end
366
366
 
367
367
  it "doesn't choke on belongs_to associations" do
368
- @shuttle.category # should not rais exception
368
+ @shuttle.category # should not raise exception
369
369
  end
370
370
 
371
371
  it "doesn't save in case of validation errors in associations defined in ascendant classes" do
@@ -381,6 +381,30 @@ describe SpaceShuttle do
381
381
  }.to raise_exception(ActiveRecord::RecordInvalid)
382
382
  end
383
383
 
384
+ it "doesn't choke on non-association related validations in association proxies" do
385
+ @shuttle.update_attribute(:name, nil)
386
+ expect {
387
+ @shuttle.save!
388
+ }.to raise_exception(ActiveRecord::RecordInvalid)
389
+ expect {
390
+ @shuttle.name = 'Name'
391
+ @shuttle.launches.build(:date => Date.today)
392
+ @shuttle.save!
393
+ }.to change(Launch, :count).by(1)
394
+ # similar for new object
395
+ shuttle = SpaceShuttle.new
396
+ expect {
397
+ shuttle.launches.build(:date => Date.today)
398
+ shuttle.save!
399
+ }.to raise_exception(ActiveRecord::RecordInvalid)
400
+ expect {
401
+ expect {
402
+ shuttle.name = 'Name'
403
+ shuttle.save!
404
+ }.to change(Launch, :count).by(1)
405
+ }.to change(SpaceShuttle, :count).by(1)
406
+ end
407
+
384
408
  end
385
409
 
386
410
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbview_cti
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.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: 2013-10-27 00:00:00.000000000 Z
12
+ date: 2013-11-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -214,7 +214,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
214
214
  version: '0'
215
215
  segments:
216
216
  - 0
217
- hash: -748447197345162789
217
+ hash: -3935376093015518215
218
218
  required_rubygems_version: !ruby/object:Gem::Requirement
219
219
  none: false
220
220
  requirements:
@@ -223,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
223
  version: '0'
224
224
  segments:
225
225
  - 0
226
- hash: -748447197345162789
226
+ hash: -3935376093015518215
227
227
  requirements: []
228
228
  rubyforge_project:
229
229
  rubygems_version: 1.8.25