kakurenbo 0.2.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d0eed74f6f1f4ee3e648f8d23f196b017a3933a0
4
- data.tar.gz: 9aba55b5f4d2191702e64feecfc348051fff0ad2
3
+ metadata.gz: f8fceaba359613cdffd663005dc7029090c9f381
4
+ data.tar.gz: 0d9f9a7cb444c4822c789701dc468df8fbee40b3
5
5
  SHA512:
6
- metadata.gz: dd0dc2d6abe2a70959bb5fdabcdf3b6970d24530208538c19af5e4d38f570f360a593a506f53ea867801f3bbb57a54ac005a45cdd711e973824888c4a2974e72
7
- data.tar.gz: a0305a8d5be99ea68c939dbd8a3e279548b8cd39e87ee14fe6c1c017655e4e87a734695b19b6c890cf0efc4b5866a8ff45bf252cca1afb53500c5b63c10572ec
6
+ metadata.gz: 3d8d53fe4d2766e9e1785cf4d3a4b45b044de1ac47c16091c5efdab73f938c6665279bca49fa93af598b92f9505f3d398777ee7e58026b610e9df05bb57de6e3
7
+ data.tar.gz: 3f179d2bbc02c7c94bce01147bf2d928af1e4c3cfa6fbeb9559a923dbf997a226e3e92a361b53c857c3007b6ff354d1ff27488a5d63c946e12dd17bfebbe9059
@@ -5,6 +5,8 @@ before_install:
5
5
  rvm:
6
6
  - 1.9.3
7
7
  - 2.1.0
8
+ - 2.1.2
8
9
  env:
9
10
  - ACTIVE_RECORD_VERSION='~> 4.0.2'
10
11
  - ACTIVE_RECORD_VERSION='~> 4.1.0'
12
+ - ACTIVE_RECORD_VERSION='~> 4.1.4'
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = <<-EOF
13
13
  provides soft delete.
14
- Kakurenbo is a re-implementation of paranoia and acts_as_paranoid for Rails4 and 3.
14
+ Kakurenbo is a re-implementation of paranoia and acts_as_paranoid for Rails4.
15
15
  implemented a function that other gems are not enough.
16
16
  EOF
17
17
 
@@ -5,6 +5,7 @@ require "active_record"
5
5
  # require kakurenbo modules.
6
6
  require "kakurenbo/version"
7
7
  require "kakurenbo/mixin_ar_base"
8
+ require "kakurenbo/mixin_ar_associations"
8
9
  require "kakurenbo/mixin_ar_relation"
9
10
  require "kakurenbo/core"
10
11
 
@@ -16,3 +17,6 @@ ActiveRecord::Base.send :include, Kakurenbo::MixinARBase
16
17
 
17
18
  # Kakurenbo Mixin to ActiveRecord::Relation.
18
19
  ActiveRecord::Relation.send :include, Kakurenbo::MixinARRelation
20
+
21
+ # Kakurenbo Mixin to ActiveRecord::Associations
22
+ ActiveRecord::Associations::Association.send :include, Kakurenbo::MixinARAssociations::Association
@@ -78,7 +78,7 @@ module Kakurenbo
78
78
  else
79
79
  return true if destroyed?
80
80
  with_transaction_returning_status do
81
- destroy_at = current_time_from_proper_timezone
81
+ destroy_at = Time.now
82
82
  run_callbacks(:destroy){ update_column kakurenbo_column, destroy_at; self }
83
83
  end
84
84
  end
@@ -121,8 +121,7 @@ module Kakurenbo
121
121
 
122
122
  with_transaction_returning_status do
123
123
  run_callbacks(:restore) do
124
- parent_deleted_at = send(kakurenbo_column)
125
- restore_associated_records(parent_deleted_at) if options[:recursive]
124
+ restore_associated_records if options[:recursive]
126
125
  update_column kakurenbo_column, nil
127
126
  self
128
127
  end
@@ -140,50 +139,29 @@ module Kakurenbo
140
139
  end
141
140
 
142
141
  private
143
- # get recoreds of association.
142
+ # All Scope of dependent association.
144
143
  #
145
- # @param association [ActiveRecord::Associations] association.
146
- # @return [Array or CollectionProxy] records.
147
- def associated_records(association)
148
- resource = send(association.name)
149
- if resource.nil?
150
- []
151
- elsif association.collection?
152
- resource.with_deleted
153
- else
154
- [resource]
155
- end
156
- end
157
-
158
- # Calls the given block once for each dependent destroy records.
159
- # @note Only call the class of paranoid.
160
- #
161
- # @param &block [Proc{|record|.. }] execute block.
162
- def each_dependent_destroy_records(&block)
163
- self.class.reflect_on_all_associations.each do |association|
164
- next unless association.options[:dependent] == :destroy
165
- next unless association.klass.paranoid?
166
-
167
- associated_records(association).each &block
168
- end
144
+ # @return [Array<ActiveRecord::Relation>] array of dependent association.
145
+ def dependent_association_scopes
146
+ self.class.reflect_on_all_associations.select { |reflection|
147
+ reflection.options[:dependent] == :destroy and reflection.klass.paranoid?
148
+ }.map { |reflection|
149
+ self.association(reflection.name).tap {|assoc| assoc.reset_scope }.scope
150
+ }
169
151
  end
170
152
 
171
153
  # Hard-Destroy associated records.
172
154
  def hard_destroy_associated_records
173
- each_dependent_destroy_records do |record|
174
- record.destroy(hard: true)
155
+ dependent_association_scopes.each do |scope|
156
+ scope.with_deleted.destroy_all(nil, hard: true)
175
157
  end
176
158
  end
177
159
 
178
160
  # Restore associated records.
179
- # @note Not restore if deleted_at older than parent_deleted_at.
180
- #
181
- # @param parent_deleted_at [Time] The time when parent was deleted.
182
- def restore_associated_records(parent_deleted_at)
183
- each_dependent_destroy_records do |record|
184
- next unless record.destroyed?
185
- next unless parent_deleted_at <= record.send(kakurenbo_column)
186
- record.restore!
161
+ # @note Record will be restored if record#deleted_at is newer than parent_deleted_at.
162
+ def restore_associated_records
163
+ dependent_association_scopes.each do |scope|
164
+ scope.restore_all
187
165
  end
188
166
  end
189
167
  end
@@ -0,0 +1,23 @@
1
+ module Kakurenbo
2
+ module MixinARAssociations
3
+ module Association
4
+ # Extend ClassMethods after include.
5
+ def self.included(base_class)
6
+ base_class.class_eval { alias_method_chain :scope, :deleted }
7
+ end
8
+
9
+ # Load deleted model, if owner is deleted.
10
+ def scope_with_deleted
11
+ if @owner.paranoid? and @owner.destroyed? and klass.paranoid?
12
+ col = klass.arel_table[klass.kakurenbo_column]
13
+ owner_deleted_at = @owner.send(@owner.class.kakurenbo_column)
14
+ condition = col.eq(nil).or(col.gteq(owner_deleted_at))
15
+
16
+ scope_without_deleted.with_deleted.where(condition)
17
+ else
18
+ scope_without_deleted
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -34,9 +34,6 @@ module Kakurenbo
34
34
  alias_method :destroy, :hard_destroy
35
35
  alias_method :destroy!, :hard_destroy!
36
36
 
37
- singleton_class.send(:alias_method, :delete, :hard_delete)
38
- singleton_class.send(:alias_method, :delete_all, :hard_delete_all)
39
-
40
37
  define_singleton_method(:paranoid?) { false }
41
38
  end
42
39
  end
@@ -55,9 +52,6 @@ module Kakurenbo
55
52
  alias_method :hard_destroy, :destroy
56
53
  alias_method :hard_destroy!, :destroy!
57
54
 
58
- singleton_class.send(:alias_method, :hard_delete, :delete)
59
- singleton_class.send(:alias_method, :hard_delete_all, :delete_all)
60
-
61
55
  class_attribute :kakurenbo_column
62
56
  include Kakurenbo::Core
63
57
  end
@@ -1,6 +1,6 @@
1
1
  module Kakurenbo
2
2
  module MixinARRelation
3
- # Extend ClassMethods after include.
3
+ # Override methods.
4
4
  def self.included(base_class)
5
5
  base_class.class_eval do
6
6
  alias_method :hard_delete_all, :delete_all
@@ -1,3 +1,3 @@
1
1
  module Kakurenbo
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -11,6 +11,11 @@ describe Kakurenbo::Core do
11
11
  create_temp_table(:paranoid_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
12
12
  create_temp_table(:paranoid_single_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
13
13
 
14
+ subject :subject_hard_delete do
15
+ create_unrelated_children
16
+ expect { parent.destroy!(hard: true) }.to change{ child_class.with_deleted.count }.by(children.length * -1)
17
+ end
18
+
14
19
  subject :subject_soft_delete do
15
20
  create_unrelated_children
16
21
  expect { parent.destroy! }.to change(child_class, :count).by(children.length * -1)
@@ -91,6 +96,12 @@ describe Kakurenbo::Core do
91
96
  end
92
97
  end
93
98
 
99
+ context 'when parent is hard-destroyed' do
100
+ it 'related children will be hard-destroyed.' do
101
+ subject_hard_delete
102
+ end
103
+ end
104
+
94
105
  context 'when parent is restored' do
95
106
  it 'related children will be restored.' do
96
107
  subject_restore
@@ -125,6 +136,12 @@ describe Kakurenbo::Core do
125
136
  end
126
137
  end
127
138
 
139
+ context 'when parent is hard-destroyed' do
140
+ it 'related children will be hard-destroyed.' do
141
+ subject_hard_delete
142
+ end
143
+ end
144
+
128
145
  context 'when parent is restored' do
129
146
  it 'related children will be restored.' do
130
147
  subject_restore
@@ -142,7 +159,7 @@ describe Kakurenbo::Core do
142
159
  end
143
160
  end
144
161
 
145
- describe 'ParanoidSingleChildModel(has_one)' do
162
+ describe 'ParanoidSingleChildModel(belongs_to)' do
146
163
  let :child_class do
147
164
  ParanoidSingleChildModel
148
165
  end
@@ -159,6 +176,12 @@ describe Kakurenbo::Core do
159
176
  end
160
177
  end
161
178
 
179
+ context 'when parent is hard-destroyed' do
180
+ it 'related children will be hard-destroyed.' do
181
+ subject_hard_delete
182
+ end
183
+ end
184
+
162
185
  context 'when parent is restored' do
163
186
  it 'related children will be restored.' do
164
187
  subject_restore
@@ -0,0 +1,122 @@
1
+ require 'spec_helper'
2
+
3
+ #
4
+ # NormalChildModel [has_many]
5
+ # ParentModel < ParanoidChildModel [has_many]
6
+ # ParanoidSingleChildModel [has_many][belongs_to]
7
+ # ParentChild - ParanoidChildModel [intermediate]
8
+ #
9
+ describe Kakurenbo::MixinARAssociations::Association do
10
+ create_temp_table(:parent_models) { |t| t.integer :child_belongs_to_id; t.datetime :deleted_at }
11
+ create_temp_table(:normal_child_models) { |t| t.integer :parent_model_id }
12
+ create_temp_table(:paranoid_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
13
+ create_temp_table(:paranoid_single_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
14
+ create_temp_table(:parents_children) { |t| t.integer :parent_model_id; t.integer :paranoid_child_model_id; t.datetime :deleted_at }
15
+
16
+ subject do
17
+ parent.destroy!
18
+ end
19
+
20
+ let :parent do
21
+ parent_class.create!
22
+ end
23
+
24
+ let! :parents_child_class do
25
+ ParentsChild.tap do |parents_child_class|
26
+ parents_child_class.belongs_to :parent_model
27
+ parents_child_class.belongs_to :paranoid_child_model
28
+ end
29
+ end
30
+
31
+ let :parent_class do
32
+ ParentModel.tap do |parent_class|
33
+ parent_class.has_many :normal_child_models, :dependent => :destroy
34
+ parent_class.has_many :paranoid_child_models, :dependent => :destroy
35
+
36
+ parent_class.has_one :child_has_one, :class_name => :ParanoidSingleChildModel, :dependent => :destroy
37
+ parent_class.belongs_to :child_belongs_to, :class_name => :ParanoidSingleChildModel, :dependent => :destroy
38
+
39
+ parent_class.has_many :parents_children, :dependent => :destroy
40
+ parent_class.has_many :children, :through => :parents_children, :source => :paranoid_child_model
41
+ end
42
+ end
43
+
44
+ describe 'NormalChildModel(has_many)' do
45
+ let! :children do
46
+ [
47
+ parent.normal_child_models.create!,
48
+ parent.normal_child_models.create!,
49
+ parent.normal_child_models.create!,
50
+ ]
51
+ end
52
+
53
+ context 'when destroyed parent is loaded' do
54
+ it 'related children will be not loaded.' do
55
+ expect(subject.normal_child_models.size).to eq(0)
56
+ end
57
+ end
58
+ end
59
+
60
+ describe 'ParanoidChildModel(has_many)' do
61
+ let! :children do
62
+ [
63
+ parent.paranoid_child_models.create!,
64
+ parent.paranoid_child_models.create!,
65
+ parent.paranoid_child_models.create!,
66
+ ]
67
+ end
68
+
69
+ context 'when destroyed parent is loaded' do
70
+ it 'related children will be loaded.' do
71
+ expect(subject.paranoid_child_models(true)).to contain_exactly(*children)
72
+ end
73
+ end
74
+ end
75
+
76
+ describe 'ParanoidSingleChildModel(has_one)' do
77
+ let! :children do
78
+ [
79
+ parent.create_child_has_one!
80
+ ]
81
+ end
82
+
83
+ context 'when destroyed parent is loaded' do
84
+ it 'related children will be loaded.' do
85
+ expect(subject.child_has_one(true)).to eq(*children)
86
+ end
87
+ end
88
+ end
89
+
90
+ describe 'ParanoidSingleChildModel(belongs_to)' do
91
+ let! :children do
92
+ [
93
+ parent.create_child_belongs_to!
94
+ ]
95
+ end
96
+
97
+ context 'when destroyed parent is loaded' do
98
+ it 'related children will be loaded.' do
99
+ expect(subject.child_belongs_to(true)).to eq(*children)
100
+ end
101
+ end
102
+ end
103
+
104
+ # Not Support ActiveRecord < 4.1
105
+ unless ActiveRecord::VERSION::STRING < "4.1"
106
+ describe 'ParanoidChild(intermediate table)' do
107
+ let! :children do
108
+ [
109
+ parent.children.create!,
110
+ parent.children.create!,
111
+ parent.children.create!,
112
+ ]
113
+ end
114
+
115
+ context 'when destroyed parent is loaded' do
116
+ it 'related children will be loaded.' do
117
+ expect(subject.children(true)).to contain_exactly(*children)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -3,6 +3,7 @@ require "bundler/setup"
3
3
  require "kakurenbo"
4
4
 
5
5
  RSpec.configure do |config|
6
+ config.color = true
6
7
  config.mock_framework = :rspec
7
8
  config.before(:all) {
8
9
  ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kakurenbo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - alfa-jpn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-11 00:00:00.000000000 Z
11
+ date: 2014-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -116,6 +116,7 @@ files:
116
116
  - kakurenbo.gemspec
117
117
  - lib/kakurenbo.rb
118
118
  - lib/kakurenbo/core.rb
119
+ - lib/kakurenbo/mixin_ar_associations.rb
119
120
  - lib/kakurenbo/mixin_ar_base.rb
120
121
  - lib/kakurenbo/mixin_ar_relation.rb
121
122
  - lib/kakurenbo/version.rb
@@ -123,6 +124,7 @@ files:
123
124
  - spec/kakurenbo/cores/callbacks_spec.rb
124
125
  - spec/kakurenbo/cores/core_spec.rb
125
126
  - spec/kakurenbo/cores/scopes_spec.rb
127
+ - spec/kakurenbo/mixin_ar_associations_spec.rb
126
128
  - spec/kakurenbo/mixin_ar_base_spec.rb
127
129
  - spec/kakurenbo/mixin_ar_relation_spec.rb
128
130
  - spec/spec_helper.rb
@@ -150,12 +152,13 @@ rubygems_version: 2.2.2
150
152
  signing_key:
151
153
  specification_version: 4
152
154
  summary: provides soft delete. Kakurenbo is a re-implementation of paranoia and acts_as_paranoid
153
- for Rails4 and 3. implemented a function that other gems are not enough.
155
+ for Rails4. implemented a function that other gems are not enough.
154
156
  test_files:
155
157
  - spec/kakurenbo/cores/associations_spec.rb
156
158
  - spec/kakurenbo/cores/callbacks_spec.rb
157
159
  - spec/kakurenbo/cores/core_spec.rb
158
160
  - spec/kakurenbo/cores/scopes_spec.rb
161
+ - spec/kakurenbo/mixin_ar_associations_spec.rb
159
162
  - spec/kakurenbo/mixin_ar_base_spec.rb
160
163
  - spec/kakurenbo/mixin_ar_relation_spec.rb
161
164
  - spec/spec_helper.rb