activerecord-prunable 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7c50d3e6673eb120db96d247c7d868fc3c5d33f8
4
- data.tar.gz: 9eb272a6c3208b92cbc3fe434e73b7b4172c493e
3
+ metadata.gz: 97a945f1fcb57b06d59c5153a1e134a91c38c76f
4
+ data.tar.gz: e32147dd1b243909a3fb972516ff22ff9c291d23
5
5
  SHA512:
6
- metadata.gz: ec970da67f57befaa9fe22bd85cc67dc2a6cdc72d92dc1867f7a84d018210acc9f551dbba83891d4fb7e6590ba25f47cd7e0e5d4112db514a16fde872e6a9c68
7
- data.tar.gz: 5d16df66278b8faabab8c6af9a960647e32b2d5834ac811147c777112771e2a8a561b0fd2ff7ff9ee591e938d5de83a10b49904198984d0a4312008d60efa8ce
6
+ metadata.gz: f27076f89b6decfa04c070d7cc6145b6e9c54c7c71a4903d82d6f8f8cc126eb0f5f3334252cc18cef590475acfd8410d2433594d0aa0793f6ed0a86354679a5b
7
+ data.tar.gz: 6dc95f9b93600595fe7188207d7c9aead81e3acef805fc2d98602bcc32bd5c2fb9e185ef789bccb9312b588d11b5e3709c38bdc65ccebb90d28db0aa3bfe2427
@@ -8,41 +8,39 @@ PATH
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activemodel (4.2.7.1)
12
- activesupport (= 4.2.7.1)
11
+ activemodel (4.2.10)
12
+ activesupport (= 4.2.10)
13
13
  builder (~> 3.1)
14
- activerecord (4.2.7.1)
15
- activemodel (= 4.2.7.1)
16
- activesupport (= 4.2.7.1)
14
+ activerecord (4.2.10)
15
+ activemodel (= 4.2.10)
16
+ activesupport (= 4.2.10)
17
17
  arel (~> 6.0)
18
- activesupport (4.2.7.1)
18
+ activesupport (4.2.10)
19
19
  i18n (~> 0.7)
20
- json (~> 1.7, >= 1.7.7)
21
20
  minitest (~> 5.1)
22
21
  thread_safe (~> 0.3, >= 0.3.4)
23
22
  tzinfo (~> 1.1)
24
- arel (6.0.3)
25
- builder (3.2.2)
26
- byebug (9.0.5)
27
- diff-lcs (1.2.5)
28
- i18n (0.7.0)
29
- json (1.8.3)
30
- minitest (5.9.0)
31
- rspec (3.5.0)
32
- rspec-core (~> 3.5.0)
33
- rspec-expectations (~> 3.5.0)
34
- rspec-mocks (~> 3.5.0)
35
- rspec-core (3.5.3)
36
- rspec-support (~> 3.5.0)
37
- rspec-expectations (3.5.0)
23
+ arel (6.0.4)
24
+ builder (3.2.3)
25
+ byebug (9.1.0)
26
+ diff-lcs (1.3)
27
+ i18n (0.8.6)
28
+ minitest (5.10.3)
29
+ rspec (3.6.0)
30
+ rspec-core (~> 3.6.0)
31
+ rspec-expectations (~> 3.6.0)
32
+ rspec-mocks (~> 3.6.0)
33
+ rspec-core (3.6.0)
34
+ rspec-support (~> 3.6.0)
35
+ rspec-expectations (3.6.0)
38
36
  diff-lcs (>= 1.2.0, < 2.0)
39
- rspec-support (~> 3.5.0)
40
- rspec-mocks (3.5.0)
37
+ rspec-support (~> 3.6.0)
38
+ rspec-mocks (3.6.0)
41
39
  diff-lcs (>= 1.2.0, < 2.0)
42
- rspec-support (~> 3.5.0)
43
- rspec-support (3.5.0)
44
- thread_safe (0.3.5)
45
- tzinfo (1.2.2)
40
+ rspec-support (~> 3.6.0)
41
+ rspec-support (3.6.0)
42
+ thread_safe (0.3.6)
43
+ tzinfo (1.2.3)
46
44
  thread_safe (~> 0.1)
47
45
 
48
46
  PLATFORMS
@@ -54,4 +52,4 @@ DEPENDENCIES
54
52
  rspec (~> 3.0)
55
53
 
56
54
  BUNDLED WITH
57
- 1.13.1
55
+ 1.15.4
data/README.md CHANGED
@@ -1,27 +1,31 @@
1
- [![Gem Version](https://badge.fury.io/rb/activerecord-prunable.svg)](https://badge.fury.io/rb/activerecord-prunable) [![Build Status](https://travis-ci.org/dr2m/activerecord-prunable.svg?branch=master)](https://travis-ci.org/dr2m/activerecord-prunable) [![Code Climate](https://codeclimate.com/github/dr2m/activerecord-prunable/badges/gpa.svg)](https://codeclimate.com/github/dr2m/activerecord-prunable)
2
-
3
- # Description
1
+ # Activerecord-prunable [![Gem Version](https://badge.fury.io/rb/activerecord-prunable.svg)](https://badge.fury.io/rb/activerecord-prunable) [![Build Status](https://travis-ci.org/dr2m/activerecord-prunable.svg?branch=master)](https://travis-ci.org/dr2m/activerecord-prunable) [![Code Climate](https://codeclimate.com/github/dr2m/activerecord-prunable/badges/gpa.svg)](https://codeclimate.com/github/dr2m/activerecord-prunable)
4
2
 
5
3
  Convenient removal of obsolete ActiveRecord models.
6
4
 
7
- # Installation
5
+ ## Installation
8
6
 
9
- ```ruby
10
- # Gemfile
7
+ Add this line to your application's Gemfile:
11
8
 
12
- gem "activerecord-prunable"
9
+ ```ruby
10
+ gem 'activerecord-prunable'
13
11
  ```
14
12
 
15
- # Usage
13
+ And then execute:
16
14
 
17
- 1. Include the `Prunable` module in the ActiveRecord model that needs to be pruned.
18
- 2. Define the `:prunable` scope that returns models to prune.
15
+ $ bundle
19
16
 
20
- Example:
17
+ Or install it yourself as:
18
+
19
+ $ gem install activerecord-prunable
20
+
21
+
22
+ ## Usage
23
+
24
+ 1. Include the `Prunable` module in the ActiveRecord model which needs to be pruned.
25
+ 2. Define the `:prunable` scope which returns models to prune.
21
26
 
22
27
  ```ruby
23
28
  class Notification < ApplicationRecord
24
-
25
29
  include ActiveRecord::Prunable
26
30
 
27
31
  scope :prunable, -> { where("created_at > ?", 1.month.ago) }
@@ -29,10 +33,23 @@ gem "activerecord-prunable"
29
33
  # You can also set type of removing records (:destroy or :delete).
30
34
  # By default it's :destroy
31
35
  prune_method :delete
36
+ end
37
+ ```
38
+
39
+ or use one of the `prune_after`, `prune_created_after`, `prune_updated_after` methods
32
40
 
41
+ ```ruby
42
+ class Notification < ApplicationRecord
43
+ include ActiveRecord::Prunable
44
+
45
+ prune_after 7.days
33
46
  end
34
47
  ```
35
48
 
49
+ `prune_after` is an alias for `prune_created_after`
50
+ `prune_created_after(TTL)` defines `where('created_at < ?', current_time - TTL)` prunable scope
51
+ `prune_updated_after(TTL)` defines `where('updated_at < ?', current_time - TTL)` prunable scope
52
+
36
53
  3. Add a `Prunable.prune!` call to a periodic task.
37
54
 
38
55
  Example:
@@ -43,39 +60,41 @@ gem "activerecord-prunable"
43
60
  every(1.day, 'models.prune', at: '04:20', thread: true) { Prunable.prune! }
44
61
  ```
45
62
 
63
+ You can also inject current time `Prunable.prune!(current_time: Time.current)`
64
+
46
65
  # Advanced Usage
47
66
 
48
- Pruning a single model:
67
+ __Pruning a single model:__
49
68
 
50
69
  ```ruby
51
70
  SomeModel.prune!
52
71
  ```
53
72
 
54
- Pruning multiple models:
73
+ __Pruning multiple models:__
74
+ Note that the `Prunable.prune!` calls `Rails.application.eager_load!`. It can decrease free memory size.
55
75
 
56
76
  ```ruby
57
77
  Prunable.prune!(SomeModel, AnotherModel)
58
78
  ```
59
79
 
60
- Set default method of pruning (:destroy or :delete):
80
+ __Set default method of pruning (:destroy or :delete):__
61
81
 
62
82
  ```ruby
63
83
  Prunable.prune!(prune_method: :delete)
64
84
  ```
65
85
 
66
- Call `:prunable` scope with params:
86
+ __Call `:prunable` scope with params:__
67
87
 
68
88
  ```ruby
69
89
  Prunable.prune!(params: [:foo, :bar])
70
90
  ```
71
91
 
72
- Getting an array of all models that include `ActiveRecord::Prunable`:
73
-
92
+ __Getting an array of all the models which include `ActiveRecord::Prunable`:__
74
93
  ```ruby
75
94
  Prunable.models
76
95
  ```
77
96
 
78
- Pruning all models that include `ActiveRecord::Prunable`:
97
+ __Pruning all models which include `ActiveRecord::Prunable`:__
79
98
 
80
99
  ```ruby
81
100
  Prunable.prune!
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "activerecord-prunable"
3
- spec.version = "0.2.2"
3
+ spec.version = "0.3.0"
4
4
  spec.authors = ["dr2m"]
5
5
  spec.email = ["maletin@maletin.work"]
6
6
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support'
2
4
  require 'active_record'
3
5
 
@@ -19,68 +21,95 @@ module ActiveRecord
19
21
 
20
22
  module ClassMethods
21
23
  def prune_method(method)
22
- return false unless check_prune_method(method)
24
+ unless check_prune_method(method)
25
+ logger.info "Incorrect prune method #{method} has been ignored for #{self}"
26
+ return false
27
+ end
23
28
 
24
29
  logger.info "Prune method #{method} has been set for #{self}"
25
30
  class_variable_set(:@@prune_method, method)
26
31
  end
27
32
 
28
- def prune!(*params, prune_method: nil)
33
+ def prune_after(duration)
34
+ prune_created_after(duration)
35
+ end
36
+
37
+ def prune_created_after(duration)
38
+ class_variable_set(:@@prune_created_after, duration)
39
+ end
40
+
41
+ def prune_updated_after(duration)
42
+ class_variable_set(:@@prune_updated_after, duration)
43
+ end
44
+
45
+ def prune!(*params, prune_method: nil, current_time: nil)
29
46
  logger.info "Pruning old records of #{self}"
30
47
  return false unless check_scope(*params)
31
48
 
32
- scope = prunable(*params)
33
- destroyed = prune_by_method(scope, prune_method)
49
+ scope = resolve_scope(*params, current_time)
50
+ destroyed_records = prune_by_method(scope, prune_method)
34
51
 
35
- if destroyed > 0
36
- logger.info "#{destroyed} records have been pruned."
52
+ if destroyed_records > 0
53
+ logger.info "#{destroyed_records} records have been removed."
37
54
  else
38
- logger.info "Nothing to prune."
55
+ logger.info 'Nothing to prune.'
39
56
  end
40
57
 
41
- destroyed
58
+ destroyed_records
42
59
  end
43
60
 
44
61
  private
45
62
 
46
63
  def check_scope(*params)
47
- unless respond_to?(:prunable)
48
- logger.info "This model has no :prunable scope, nothing to prune."
64
+ pruning_means_count = [
65
+ respond_to?(:prunable),
66
+ class_variable_defined?(:@@prune_created_after),
67
+ class_variable_defined?(:@@prune_updated_after)
68
+ ].count(true)
69
+
70
+ if pruning_means_count.zero?
71
+ logger.info "The model hasn't got prunable scope or TTL, action is not allowed."
49
72
  return false
50
73
  end
51
74
 
52
- unless prunable(*params).is_a?(::ActiveRecord::Relation)
53
- logger.info ":prunable is not a relation, nothing to prune."
75
+ if pruning_means_count > 1
76
+ logger.info 'Ambiguity detected, action is not allowed.'
54
77
  return false
55
78
  end
56
79
 
57
80
  true
58
81
  end
59
82
 
60
- def check_prune_method(method)
61
- unless [:destroy, :delete].include?(method)
62
- logger.info "Incorrect prune method #{method} will be ignored for #{self}"
63
- return false
83
+ def resolve_scope(*params, current_time)
84
+ current_time ||= Time.current
85
+
86
+ case
87
+ when respond_to?(:prunable)
88
+ prunable(*params)
89
+ when class_variable_defined?(:@@prune_created_after)
90
+ where('created_at < ?', current_time - class_variable_get(:@@prune_created_after))
91
+ when class_variable_defined?(:@@prune_updated_after)
92
+ where('updated_at < ?', current_time - class_variable_get(:@@prune_updated_after))
64
93
  end
65
- true
94
+ end
95
+
96
+ def check_prune_method(method)
97
+ %i[destroy delete].include?(method)
66
98
  end
67
99
 
68
100
  def prune_by_method(scope, prune_method)
69
- unless class_variable_defined?(:@@prune_method)
70
- prune_method = prune_method || :destroy
71
- else
72
- prune_method = class_variable_get(:@@prune_method)
73
- end
101
+ prune_method = if class_variable_defined?(:@@prune_method)
102
+ class_variable_get(:@@prune_method)
103
+ else
104
+ prune_method || :destroy
105
+ end
74
106
 
75
107
  return false unless check_prune_method(prune_method)
76
108
 
77
109
  logger.info "Prune method is #{prune_method}"
78
110
 
79
- if prune_method == :delete
80
- scope.delete_all
81
- else
82
- scope.destroy_all.size
83
- end
111
+ return scope.delete_all if prune_method == :delete
112
+ scope.destroy_all.size
84
113
  end
85
114
  end
86
115
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record/prunable'
2
4
 
3
5
  module Prunable
@@ -11,6 +13,7 @@ module Prunable
11
13
 
12
14
  def prune!(*models, prune_method: nil, params: [])
13
15
  models = self.models if models.empty?
16
+
14
17
  models.each do |model|
15
18
  model.prune!(*params, prune_method: prune_method)
16
19
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-prunable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dr2m
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-24 00:00:00.000000000 Z
11
+ date: 2017-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  version: '0'
116
116
  requirements: []
117
117
  rubyforge_project:
118
- rubygems_version: 2.6.6
118
+ rubygems_version: 2.5.1
119
119
  signing_key:
120
120
  specification_version: 4
121
121
  summary: Convenient removal of obsolete ActiveRecord models.