acread 0.5.3 → 0.6.0
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/Gemfile +4 -0
- data/README.md +12 -5
- data/VERSION +1 -1
- data/acread.gemspec +5 -2
- data/lib/acread.rb +6 -1
- data/lib/acread/active_record_ext.rb +2 -1
- data/lib/acread/deprecatable.rb +32 -19
- data/test/test_acread.rb +17 -6
- metadata +19 -3
data/Gemfile
CHANGED
@@ -3,6 +3,10 @@ source 'http://rubygems.org/'
|
|
3
3
|
# gem dependencies
|
4
4
|
gem 'rails', '>= 3.0'
|
5
5
|
|
6
|
+
if Gem::Version.new(String.new(RUBY_VERSION)) > Gem::Version.new('1.9')
|
7
|
+
gem 'continuable', :path => '~/Projects/continuable'
|
8
|
+
end
|
9
|
+
|
6
10
|
# dependencies to develop your gem here.
|
7
11
|
# Include everything needed to run rake, tests, features, etc.
|
8
12
|
group :development do
|
data/README.md
CHANGED
@@ -9,6 +9,8 @@ When you deprecate an attribute, acread can helps you in 3 ways :
|
|
9
9
|
1. ignore this atribute when serializing the object through to_json, to_xml ...
|
10
10
|
1. helps your zero downtime migration by ignoring the attribute for objects already in memory when saving to database.
|
11
11
|
|
12
|
+
Have a look at this [London Ruby Group Lightning talk](http://skillsmatter.com/podcast/ajax-ria/hulk-smash) for a quick description of that 3 steps.
|
13
|
+
|
12
14
|
# Usage
|
13
15
|
|
14
16
|
## Installation
|
@@ -29,21 +31,26 @@ end
|
|
29
31
|
## find attribute usage
|
30
32
|
you can catch the `DeprecatedAttributeError` exception and for example put a backtrace in a specific logger.
|
31
33
|
|
34
|
+
If you are using ruby > 1.9, Acread use the gem continuable (https://github.com/cmaruz/continuable).
|
35
|
+
The DeprecatedAttributeError can then be continued, this mean you can catch it and continue normal ActiveRecord behavior.
|
36
|
+
You're code hunting can then be done without any effect on your datas by simply catching the exception, logging and continuing.
|
37
|
+
|
32
38
|
```ruby
|
33
39
|
class ApplicationController
|
34
40
|
rescue_from DeprecatedAttributeError, :with => :log_deprecate
|
35
|
-
|
41
|
+
|
36
42
|
private
|
37
|
-
|
43
|
+
|
38
44
|
def deprecated_logger
|
39
45
|
@@deprecated_logger ||= Logger.new("#{Rails.root}/log/deprecated_calls.log")
|
40
46
|
end
|
41
|
-
|
47
|
+
|
42
48
|
def log_deprecated e
|
43
49
|
deprecated_logger.error(e.stacktrace.join("\n"))
|
50
|
+
e.continue
|
44
51
|
end
|
45
52
|
end
|
46
|
-
```
|
53
|
+
```
|
47
54
|
|
48
55
|
## zero downtime migration
|
49
56
|
When you are done with cleaning your code from any usage of deprecated attributes, you can prepare a migration including some drop_columns.
|
@@ -62,7 +69,7 @@ class RemoveLongNames < ActiveRecord::Migration
|
|
62
69
|
end
|
63
70
|
end
|
64
71
|
```
|
65
|
-
|
72
|
+
|
66
73
|
Then you can safely follow the steps :
|
67
74
|
|
68
75
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/acread.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "acread"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["yann ARMAND", "Nick Campbell"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2013-02-18"
|
13
13
|
s.description = "An ActiveRecord Extension to deprecate attributes"
|
14
14
|
s.email = "yann@harakys.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -41,6 +41,7 @@ Gem::Specification.new do |s|
|
|
41
41
|
|
42
42
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
43
43
|
s.add_runtime_dependency(%q<rails>, [">= 3.0"])
|
44
|
+
s.add_runtime_dependency(%q<continuable>, [">= 0"])
|
44
45
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
45
46
|
s.add_development_dependency(%q<rdoc>, [">= 3.12"])
|
46
47
|
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
@@ -48,6 +49,7 @@ Gem::Specification.new do |s|
|
|
48
49
|
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
49
50
|
else
|
50
51
|
s.add_dependency(%q<rails>, [">= 3.0"])
|
52
|
+
s.add_dependency(%q<continuable>, [">= 0"])
|
51
53
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
52
54
|
s.add_dependency(%q<rdoc>, [">= 3.12"])
|
53
55
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
@@ -56,6 +58,7 @@ Gem::Specification.new do |s|
|
|
56
58
|
end
|
57
59
|
else
|
58
60
|
s.add_dependency(%q<rails>, [">= 3.0"])
|
61
|
+
s.add_dependency(%q<continuable>, [">= 0"])
|
59
62
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
60
63
|
s.add_dependency(%q<rdoc>, [">= 3.12"])
|
61
64
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
data/lib/acread.rb
CHANGED
data/lib/acread/deprecatable.rb
CHANGED
@@ -1,32 +1,45 @@
|
|
1
|
+
require 'continuable' if Acread::run_19?
|
2
|
+
|
1
3
|
module Deprecatable
|
2
4
|
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
3
9
|
ACCESSORS = [ '', '=', '_before_type_cast', '?', '_changed?', '_change', '_will_change!', '_was']
|
4
10
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
11
|
+
module ClassMethods
|
12
|
+
def deprecate_attribute(attr, opts={})
|
13
|
+
opts ||={}
|
14
|
+
@deprecated_attributes ||=[]
|
15
|
+
@deprecated_attributes << attr.to_s
|
16
|
+
overide_accessors attr, opts
|
17
|
+
end
|
10
18
|
|
11
|
-
|
12
|
-
|
13
|
-
|
19
|
+
def deprecated_attributes
|
20
|
+
@deprecated_attributes
|
21
|
+
end
|
14
22
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
23
|
+
def accessors
|
24
|
+
# TODO: replace this constant by an ActiveRecord inspection
|
25
|
+
ACCESSORS
|
26
|
+
end
|
19
27
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
28
|
+
def overide_accessors(attr, opts)
|
29
|
+
msg = "You can't access atribute #{attr}, it has been deprecated"
|
30
|
+
accessors.each do |term|
|
31
|
+
define_method("#{attr}#{term}") do |*args|
|
32
|
+
raise DeprecatedAttributeError, msg
|
33
|
+
(args.length >0 ? super(args) : super()).first # call ActiveRecord behavior if previous exception have been continued
|
34
|
+
end
|
25
35
|
end
|
26
36
|
end
|
27
37
|
end
|
28
38
|
|
29
|
-
|
39
|
+
class DeprecatedAttributeError < Exception
|
40
|
+
include Continuable if Acread::run_19?
|
41
|
+
end
|
30
42
|
|
31
|
-
class DeprecatedAttributeError < RuntimeError
|
32
43
|
end
|
44
|
+
|
45
|
+
|
data/test/test_acread.rb
CHANGED
@@ -25,17 +25,28 @@ class TestAcread < Test::Unit::TestCase
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def test_cretor_with_deprecated_field_raise_exception
|
28
|
-
assert_raise(DeprecatedAttributeError) { Person.create(:long_name => 'should not see this') }
|
28
|
+
assert_raise(Deprecatable::DeprecatedAttributeError) { Person.create(:long_name => 'should not see this') }
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_read_deprecated_raise_exception
|
32
|
-
assert_raise(DeprecatedAttributeError) { @bob.long_name }
|
32
|
+
assert_raise(Deprecatable::DeprecatedAttributeError) { @bob.long_name }
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_write_deprecated_raise_exception
|
36
|
-
assert_raise(DeprecatedAttributeError) { @bob.long_name = 'Bon' }
|
36
|
+
assert_raise(Deprecatable::DeprecatedAttributeError) { @bob.long_name = 'Bon' }
|
37
37
|
end
|
38
38
|
|
39
|
+
def test_write_dreprecated_with_continuation
|
40
|
+
return true unless Acread::run_19?
|
41
|
+
v = 'failure'
|
42
|
+
begin
|
43
|
+
@bob.long_name = 'bobob'
|
44
|
+
v = @bob.long_name
|
45
|
+
rescue Deprecatable::DeprecatedAttributeError => e
|
46
|
+
e.continue
|
47
|
+
end
|
48
|
+
assert_equal 'bobob', v
|
49
|
+
end
|
39
50
|
|
40
51
|
def test_hash_exclude_deprecated_attributes
|
41
52
|
h = @bob.serializable_hash
|
@@ -50,18 +61,18 @@ class TestAcread < Test::Unit::TestCase
|
|
50
61
|
def test_non_deprecated_class_can_read_all_attributes
|
51
62
|
assert @james.long_name.is_a? String
|
52
63
|
end
|
53
|
-
|
64
|
+
|
54
65
|
def test_non_deprecated_class_can_write_all_attributes
|
55
66
|
s = 'james the short'
|
56
67
|
@james.long_name = s
|
57
68
|
assert @james.long_name == s
|
58
69
|
end
|
59
|
-
|
70
|
+
|
60
71
|
def test_non_deprecated_class_columns_output_all_attributes
|
61
72
|
h = @james.send(:columns).map(&:name)
|
62
73
|
assert h.include? 'long_name'
|
63
74
|
end
|
64
|
-
|
75
|
+
|
65
76
|
def test_non_deprecated_class_hash_output_all_attributes
|
66
77
|
h = @james.serializable_hash
|
67
78
|
assert h.keys.include? 'long_name'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acread
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-02-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
@@ -28,6 +28,22 @@ dependencies:
|
|
28
28
|
- - ! '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: '3.0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: continuable
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
31
47
|
- !ruby/object:Gem::Dependency
|
32
48
|
name: shoulda
|
33
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,7 +159,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
143
159
|
version: '0'
|
144
160
|
segments:
|
145
161
|
- 0
|
146
|
-
hash: -
|
162
|
+
hash: -2723091470666414279
|
147
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
164
|
none: false
|
149
165
|
requirements:
|