immortal 2.0.0 → 3.0.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +114 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +1 -1
- data/LICENSE.txt +21 -0
- data/README.md +21 -44
- data/Rakefile +2 -2
- data/immortal.gemspec +28 -21
- data/lib/immortal.rb +45 -39
- data/lib/immortal/belongs_to.rb +4 -3
- data/lib/immortal/belongs_to_builder.rb +25 -30
- data/lib/immortal/singular_association.rb +91 -109
- data/lib/immortal/version.rb +3 -0
- metadata +69 -10
- data/LICENSE +0 -9
- data/spec/immortal_spec.rb +0 -383
- data/spec/spec_helper.rb +0 -145
data/lib/immortal/belongs_to.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
require 'immortal/belongs_to_builder'
|
2
2
|
|
3
|
-
#Include this to add {with/only}_deleted_ accessors for singular associations
|
4
3
|
module Immortal
|
4
|
+
# Includes this to add +association_{with/only}_deleted+ accessors for belongs_to
|
5
|
+
# associations.
|
5
6
|
module BelongsTo
|
6
7
|
def self.included(base)
|
7
8
|
base.class_eval do
|
8
9
|
class << self
|
9
|
-
|
10
10
|
# Add with/how_deleted singular association readers
|
11
11
|
def belongs_to_mortal(name, scope = nil, options = {})
|
12
|
-
|
12
|
+
reflection = BelongsToBuilder.build(self, name, scope, options)
|
13
|
+
ActiveRecord::Reflection.add_reflection self, name, reflection
|
13
14
|
end
|
14
15
|
|
15
16
|
alias_method :belongs_to_immortal, :belongs_to
|
@@ -2,45 +2,40 @@ require 'active_record'
|
|
2
2
|
require 'immortal/singular_association'
|
3
3
|
|
4
4
|
module Immortal
|
5
|
+
# Builds a +belongs_to+ association with +_with_deleted+ and +_only_deleted+
|
6
|
+
# readers.
|
5
7
|
class BelongsToBuilder < ::ActiveRecord::Associations::Builder::BelongsTo
|
6
|
-
|
7
|
-
def define_accessors
|
8
|
+
def self.define_accessors(mixin, reflection)
|
8
9
|
super
|
9
|
-
define_deletables
|
10
|
+
define_deletables(mixin, reflection)
|
10
11
|
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
13
|
+
def self.define_deletables(mixin, reflection)
|
14
|
+
define_with_deleted_reader(mixin, reflection)
|
15
|
+
define_only_deleted_reader(mixin, reflection)
|
16
|
+
end
|
17
|
+
private_class_method :define_deletables
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
def self.define_with_deleted_reader(mixin, reflection)
|
20
|
+
name = reflection.name
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
22
|
+
mixin.redefine_method("#{name}_with_deleted") do |*params|
|
23
|
+
assoc = association(name)
|
24
|
+
assoc.send(:extend, SingularAssociation)
|
25
|
+
assoc.with_deleted_reader(*params)
|
27
26
|
end
|
27
|
+
end
|
28
|
+
private_class_method :define_with_deleted_reader
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
model.redefine_method("#{name}_only_deleted") do |*params|
|
30
|
+
def self.define_only_deleted_reader(mixin, reflection)
|
31
|
+
name = reflection.name
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
mixin.redefine_method("#{name}_only_deleted") do |*params|
|
34
|
+
assoc = association(name)
|
35
|
+
assoc.send(:extend, SingularAssociation)
|
36
|
+
assoc.only_deleted_reader(*params)
|
38
37
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end #InstanceMethods
|
43
|
-
|
38
|
+
end
|
39
|
+
private_class_method :define_only_deleted_reader
|
44
40
|
end
|
45
41
|
end
|
46
|
-
|
@@ -1,4 +1,6 @@
|
|
1
1
|
module Immortal
|
2
|
+
# Mixin to provide the singular association readers for +_only_deleted+ and
|
3
|
+
# +_with_deleted+.
|
2
4
|
module SingularAssociation
|
3
5
|
attr_reader :with_deleted_target, :only_deleted_target
|
4
6
|
|
@@ -12,140 +14,120 @@ module Immortal
|
|
12
14
|
|
13
15
|
private
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def reset_with_deleted
|
20
|
-
@with_deleted_loaded = false
|
21
|
-
ActiveRecord::IdentityMap.remove(with_deleted_target) if supports_indetity_map? && with_deleted_target
|
22
|
-
@with_deleted_target = nil
|
23
|
-
end
|
17
|
+
attr_reader :with_deleted_loaded, :only_deleted_loaded
|
18
|
+
alias with_deleted_loaded? with_deleted_loaded
|
19
|
+
alias only_deleted_loaded? only_deleted_loaded
|
24
20
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
21
|
+
def reset_with_deleted
|
22
|
+
@with_deleted_loaded = false
|
23
|
+
@with_deleted_target = nil
|
24
|
+
end
|
30
25
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
def reset_only_deleted
|
27
|
+
@only_deleted_loaded = false
|
28
|
+
@only_deleted_target = nil
|
29
|
+
end
|
35
30
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
def with_deleted_loaded!
|
32
|
+
@with_deleted_loaded = true
|
33
|
+
@with_deleted_stale_state = stale_state
|
34
|
+
end
|
40
35
|
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
def only_deleted_loaded!
|
37
|
+
@only_deleted_loaded = true
|
38
|
+
@only_deleted_stale_state = stale_state
|
39
|
+
end
|
44
40
|
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
def stale_with_deleted_target?
|
42
|
+
with_deleted_loaded? && @with_deleted_stale_state != stale_state
|
43
|
+
end
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
def stale_only_deleted_target?
|
46
|
+
only_deleted_loaded? && @only_deleted_stale_state != stale_state
|
47
|
+
end
|
52
48
|
|
53
|
-
|
54
|
-
|
55
|
-
|
49
|
+
def reload_only_deleted
|
50
|
+
reset_only_deleted
|
51
|
+
reset_scope
|
52
|
+
load_only_deleted_target
|
53
|
+
self if only_deleted_target
|
54
|
+
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
56
|
+
def reload_with_deleted
|
57
|
+
reset_with_deleted
|
58
|
+
reset_scope
|
59
|
+
load_with_deleted_target
|
60
|
+
self if with_deleted_target
|
61
|
+
end
|
63
62
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
63
|
+
def find_with_deleted_target?
|
64
|
+
!with_deleted_loaded? &&
|
65
|
+
(!owner.new_record? || foreign_key_present?) &&
|
66
|
+
klass
|
67
|
+
end
|
70
68
|
|
71
|
-
|
72
|
-
|
73
|
-
|
69
|
+
def find_only_deleted_target?
|
70
|
+
!only_deleted_loaded? &&
|
71
|
+
(!owner.new_record? || foreign_key_present?) &&
|
72
|
+
klass
|
73
|
+
end
|
74
74
|
|
75
|
-
|
76
|
-
|
75
|
+
def load_with_deleted_target
|
76
|
+
if find_with_deleted_target?
|
77
|
+
@with_deleted_target ||= find_with_deleted_target
|
77
78
|
end
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
85
|
-
rescue NameError
|
86
|
-
nil
|
87
|
-
ensure
|
88
|
-
@with_deleted_target ||= find_with_deleted_target
|
89
|
-
end
|
90
|
-
end
|
91
|
-
with_deleted_loaded! unless with_deleted_loaded?
|
92
|
-
with_deleted_target
|
93
|
-
rescue ActiveRecord::RecordNotFound
|
94
|
-
with_deleted_reset
|
95
|
-
end
|
80
|
+
with_deleted_loaded! unless with_deleted_loaded?
|
81
|
+
with_deleted_target
|
82
|
+
rescue ActiveRecord::RecordNotFound
|
83
|
+
with_deleted_reset
|
84
|
+
end
|
96
85
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
if supports_indetity_map? && association_class && association_class.respond_to?(:base_class)
|
101
|
-
@only_deleted_target = ActiveRecord::IdentityMap.get(association_class, owner[reflection.foreign_key])
|
102
|
-
end
|
103
|
-
rescue NameError
|
104
|
-
nil
|
105
|
-
ensure
|
106
|
-
@only_deleted_target ||= find_only_deleted_target
|
107
|
-
end
|
108
|
-
end
|
109
|
-
only_deleted_loaded! unless only_deleted_loaded?
|
110
|
-
only_deleted_target
|
111
|
-
rescue ActiveRecord::RecordNotFound
|
112
|
-
only_deleted_reset
|
86
|
+
def load_only_deleted_target
|
87
|
+
if find_only_deleted_target?
|
88
|
+
@only_deleted_target ||= find_only_deleted_target
|
113
89
|
end
|
114
90
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
end
|
91
|
+
only_deleted_loaded! unless only_deleted_loaded?
|
92
|
+
only_deleted_target
|
93
|
+
rescue ActiveRecord::RecordNotFound
|
94
|
+
only_deleted_reset
|
95
|
+
end
|
121
96
|
|
122
|
-
|
97
|
+
def reader_with_deleted(force_reload = false)
|
98
|
+
if force_reload
|
99
|
+
klass.uncached { reload_with_deleted } if klass
|
100
|
+
elsif !with_deleted_loaded? || stale_with_deleted_target?
|
101
|
+
reload_with_deleted
|
123
102
|
end
|
124
103
|
|
125
|
-
|
126
|
-
|
127
|
-
if force_reload
|
128
|
-
klass.uncached { reload_only_deleted } if klass
|
129
|
-
elsif !only_deleted_loaded? || stale_only_deleted_target?
|
130
|
-
reload_only_deleted
|
131
|
-
end
|
104
|
+
with_deleted_target
|
105
|
+
end
|
132
106
|
|
133
|
-
|
107
|
+
def reader_only_deleted(force_reload = false)
|
108
|
+
if force_reload
|
109
|
+
klass.uncached { reload_only_deleted } if klass
|
110
|
+
elsif !only_deleted_loaded? || stale_only_deleted_target?
|
111
|
+
reload_only_deleted
|
134
112
|
end
|
135
113
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
114
|
+
only_deleted_target
|
115
|
+
end
|
116
|
+
|
117
|
+
def find_with_deleted_target
|
118
|
+
return nil unless klass
|
119
|
+
klass.unscoped do
|
120
|
+
scope.first.tap { |record| set_inverse_instance(record) }
|
141
121
|
end
|
122
|
+
end
|
142
123
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
124
|
+
def find_only_deleted_target
|
125
|
+
return nil unless klass
|
126
|
+
klass.unscoped do
|
127
|
+
scope.where(deleted: true).first.tap do |record|
|
128
|
+
set_inverse_instance(record)
|
147
129
|
end
|
148
130
|
end
|
149
|
-
|
131
|
+
end
|
150
132
|
end
|
151
133
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: immortal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordi Romero
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date:
|
17
|
+
date: 2017-05-09 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activerecord
|
@@ -22,28 +22,42 @@ dependencies:
|
|
22
22
|
requirements:
|
23
23
|
- - "~>"
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: 4.
|
25
|
+
version: 4.1.0
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
28
|
version_requirements: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - "~>"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 4.
|
32
|
+
version: 4.1.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rspec
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: 3.6.0
|
40
40
|
type: :development
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
46
|
+
version: 3.6.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec-its
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
62
|
name: sqlite3
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +100,48 @@ dependencies:
|
|
86
100
|
- - "~>"
|
87
101
|
- !ruby/object:Gem::Version
|
88
102
|
version: '10.0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: rubocop
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rubocop-rspec
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: reek
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
89
145
|
description: Typical paranoid gem built for Rails 4 and with the minimum code needed
|
90
146
|
to satisfy acts_as_paranoid's API
|
91
147
|
email:
|
@@ -96,8 +152,12 @@ extensions: []
|
|
96
152
|
extra_rdoc_files: []
|
97
153
|
files:
|
98
154
|
- ".gitignore"
|
155
|
+
- ".rspec"
|
156
|
+
- ".rubocop.yml"
|
157
|
+
- CHANGELOG.md
|
158
|
+
- CODE_OF_CONDUCT.md
|
99
159
|
- Gemfile
|
100
|
-
- LICENSE
|
160
|
+
- LICENSE.txt
|
101
161
|
- README.md
|
102
162
|
- Rakefile
|
103
163
|
- immortal.gemspec
|
@@ -105,8 +165,7 @@ files:
|
|
105
165
|
- lib/immortal/belongs_to.rb
|
106
166
|
- lib/immortal/belongs_to_builder.rb
|
107
167
|
- lib/immortal/singular_association.rb
|
108
|
-
-
|
109
|
-
- spec/spec_helper.rb
|
168
|
+
- lib/immortal/version.rb
|
110
169
|
homepage: http://github.com/teambox/immortal
|
111
170
|
licenses:
|
112
171
|
- MIT
|
@@ -127,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
186
|
version: '0'
|
128
187
|
requirements: []
|
129
188
|
rubyforge_project:
|
130
|
-
rubygems_version: 2.
|
189
|
+
rubygems_version: 2.6.12
|
131
190
|
signing_key:
|
132
191
|
specification_version: 4
|
133
192
|
summary: Replacement for acts_as_paranoid for Rails 4
|