temporal_scopes 0.0.1 → 0.0.2

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: 01054fa8697a5d6a48d6cd36198905e919911a2e
4
- data.tar.gz: 447d77b095f5c0d98c4972ab4debf32770e85c12
3
+ metadata.gz: a0bb59fb20ec57703464efa1db45f23340de3450
4
+ data.tar.gz: baeec6001c3138410bd94561be1339292948b4fb
5
5
  SHA512:
6
- metadata.gz: 395a9c350971e89678b547a9b6397eedc9817637f4c4f5ec98a299352e6acd95eee54ff9fd3723d63fb15dd367da221445b8d7e6b6e55137eca01a97a76560a5
7
- data.tar.gz: aa871fb961337b880c652c9aef1507a094904bf5dd85d2ed3d73bf311e193a112dced1e6d392ca4a6876362d8a4da78f74b54c3b36e76832b8ac59dd3f0d9117
6
+ metadata.gz: 3936bb8540a87a2f6aff81483a0e6ee5e3fa623466bb5c7c426097342280e74add1ff5b92b66c14c95f99b114d077ebade22b186b106ff7d27560c7c7cdc4c51
7
+ data.tar.gz: ff2003aff6d0c39d4a0fef33490dc95e73da1d2a062596b60ba6fb74e9d3c8f9c597626f2c10c457b2bf9efaee8711848c35ebb5454433b5542e8c1a312796d3
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # TemporalScopes [![Build Status](https://travis-ci.org/fiedl/temporal_scopes.svg?branch=master)](https://travis-ci.org/fiedl/temporal_scopes)
1
+ # TemporalScopes [![Build Status](https://travis-ci.org/fiedl/temporal_scopes.svg?branch=master)](https://travis-ci.org/fiedl/temporal_scopes) [![Gem Version](https://badge.fury.io/rb/temporal_scopes.svg)](http://badge.fury.io/rb/temporal_scopes)
2
2
 
3
3
  Providing temporal scopes for an ActiveRecord model to allow queries by time. For example, `MyModel.now.where(...)`, `my_model.archive`, `MyModel.past.where(...)`.
4
4
 
@@ -50,7 +50,9 @@ Further [documentation can be found on rubydoc.info](http://rubydoc.info/github/
50
50
 
51
51
  ### Caveats
52
52
 
53
+ * This gem requires Rails 4.
53
54
  * There is only one `valid_from` and one `valid_to` time per object. Therefore, you can't keep track of first archiving an object and later un-archiving it. Un-archiving an object loses the information of first archiving it.
55
+ * Currently, the future is not handled (`Article.future` and `article.archive at: 1.hour.from.now` do not work.) But this is planned to be implemented in the future.
54
56
 
55
57
  ## Installation
56
58
 
@@ -3,38 +3,125 @@ require 'active_record'
3
3
  module TemporalScopes
4
4
  module HasTemporalScopes
5
5
 
6
+ # Adds scopes and methods for handing temporal filtering.
7
+ #
8
+ # ## Make an `ActiveRecord` have temporal scopes
9
+ #
10
+ # class Article < ActiveRecord::Base
11
+ # has_temporal_scopes
12
+ #
13
+ # end
14
+ #
15
+ # ## Archive an object
16
+ #
17
+ # current_article = Article.create(title: 'My new article', body: 'Lorem ipsum')
18
+ #
19
+ # past_article = Article.create(title: 'My new article', body: 'Lorem ipsum')
20
+ # past_article.archive
21
+ #
22
+ # # or provide a datetime:
23
+ # past_article.archive at: 1.hour.ago
24
+ #
25
+ # ## Use temporal scopes for filtering
26
+ #
27
+ # Article.now # => [current_article]
28
+ # Article.past # => [past_article]
29
+ # Article.with_past # => [current_article, past_article]
30
+ #
31
+ # Note that the **default scope** is set to `now`.
32
+ #
33
+ # Article.all # => [current_article]
34
+ # Article.now # => [current_article]
35
+ # Article.with_past # => [current_article, past_article]
36
+ # Article.without_temporal_condition # => [current_article, past_article]
37
+ #
6
38
  def has_temporal_scopes
7
39
 
8
- scope :without_temporal_condition, -> {
9
- relation = unscope(where: [:valid_from, :valid_to])
10
- relation.where_values.delete_if { |query| query.to_sql.include?("\"valid_from\"") || query.to_sql.include?("\"valid_to\"") }
11
- relation
12
- }
13
-
14
- scope :now, -> {
15
- without_temporal_condition
16
- .where(arel_table[:valid_from].eq(nil).or(arel_table[:valid_from].lteq(Time.zone.now)))
17
- .where(arel_table[:valid_to].eq(nil).or(arel_table[:valid_to].gteq(Time.zone.now)))
18
- }
19
- scope :past, -> { without_temporal_condition.where('valid_to < ?', Time.zone.now) }
20
- scope :with_past, -> { without_temporal_condition }
21
-
22
40
  default_scope { now }
23
41
 
24
42
  extend ClassMethods
25
43
  include InstanceMethods
26
44
  end
27
45
 
46
+ # The following class methods and scopes are added to
47
+ # `ActiveRecord::Base` classes that have been called
48
+ # `has_temporal_scopes` on.
49
+ #
28
50
  module ClassMethods
51
+
52
+ # Removes temporal conditions from the query.
53
+ #
54
+ # @example
55
+ # Article.where(valid_to: 10.days.ago..1.day.ago) # => [] (due to default scope.)
56
+ # Article.without_temporal_condition.where(valid_to: 10.days.ago..1.day.ago) # returns the desired articles.
57
+ #
58
+ # @return [ActiveRecord::Relation] the relation without temporal conditions on `valid_from` and `valid_to`.
59
+ #
60
+ def without_temporal_condition
61
+ relation = unscope(where: [:valid_from, :valid_to])
62
+ relation.where_values.delete_if { |query| query.to_sql.include?("\"valid_from\"") || query.to_sql.include?("\"valid_to\"") } if relation && relation.where_values
63
+ relation
64
+ end
65
+
66
+ # Filters for only current objects.
67
+ #
68
+ # This is the default scope.
69
+ #
70
+ # @return [ActiveRecord::Relation] only current objects.
71
+ #
72
+ def now
73
+ without_temporal_condition
74
+ .where(arel_table[:valid_from].eq(nil).or(arel_table[:valid_from].lteq(Time.zone.now)))
75
+ .where(arel_table[:valid_to].eq(nil).or(arel_table[:valid_to].gteq(Time.zone.now)))
76
+ end
77
+
78
+ # Filters for only past objects.
79
+ #
80
+ # @return [ActiveRecord::Relation] only past objects.
81
+ #
82
+ # @example Getting only archived articles by an author.
83
+ # author.articles.past
84
+ #
85
+ def past
86
+ without_temporal_condition.where('valid_to < ?', Time.zone.now)
87
+ end
88
+
89
+ # Removes the filters such that past and present
90
+ # objects are returned.
91
+ #
92
+ # @return [ActiveRecord::Relation] past and current objects.
93
+ #
94
+ def with_past
95
+ without_temporal_condition
96
+ end
97
+
29
98
  end
30
-
99
+
100
+ # The following instance methods are added to
101
+ # `ActiveRecord::Base` objects, which classes have
102
+ # been called `has_temporal_scopes` on.
103
+ #
31
104
  module InstanceMethods
32
105
 
106
+ # Archives an object, that is, makes it a past object.
107
+ #
108
+ # @param params [Hash] a hash of parameters.
109
+ # @option params :at [DateTime] (Time.zonw.now) when to archive the object, i.e. the time when the present object becomes a past object, i.e. expires.
110
+ #
111
+ # @return [ActiveRecord::Base] the archived object.
112
+ #
113
+ # @example Archiving an object now.
114
+ # article.archive
115
+ #
116
+ # @example Archiving an object with effect 4 hours ago.
117
+ # article.archive at: 4.hours.ago
118
+ #
33
119
  def archive(params = {})
34
120
  unless self.valid_to
35
121
  archive_at = params[:at] || Time.zone.now
36
122
  update_attribute(:valid_to, archive_at)
37
123
  end
124
+ return self
38
125
  end
39
126
 
40
127
  end
@@ -1,3 +1,3 @@
1
1
  module TemporalScopes
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: temporal_scopes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Fiedlschuster