by_star 3.0.0 → 4.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/.github/workflows/mysql.yml +92 -0
- data/.github/workflows/postgresql.yml +99 -0
- data/.gitignore +1 -0
- data/.travis.yml +67 -36
- data/CHANGELOG.md +15 -0
- data/README.md +172 -133
- data/UPGRADING +1 -3
- data/by_star.gemspec +2 -2
- data/lib/by_star/base.rb +16 -15
- data/lib/by_star/between.rb +81 -52
- data/lib/by_star/directional.rb +2 -4
- data/lib/by_star/kernel/date.rb +0 -9
- data/lib/by_star/kernel/in_time_zone.rb +20 -0
- data/lib/by_star/normalization.rb +52 -23
- data/lib/by_star/orm/active_record/by_star.rb +20 -6
- data/lib/by_star/orm/mongoid/by_star.rb +20 -6
- data/lib/by_star/version.rb +1 -1
- data/lib/by_star.rb +1 -0
- data/spec/database.yml +1 -1
- data/spec/fixtures/active_record/models.rb +2 -2
- data/spec/fixtures/mongoid/models.rb +1 -1
- data/spec/fixtures/shared/seeds.rb +10 -0
- data/spec/gemfiles/Gemfile.rails +5 -0
- data/spec/gemfiles/Gemfile.rails32 +7 -0
- data/spec/gemfiles/Gemfile.rails40 +1 -1
- data/spec/gemfiles/Gemfile.rails41 +1 -1
- data/spec/gemfiles/Gemfile.rails42 +2 -2
- data/spec/gemfiles/Gemfile.rails50 +1 -4
- data/spec/gemfiles/Gemfile.rails51 +1 -4
- data/spec/gemfiles/Gemfile.rails52 +7 -0
- data/spec/gemfiles/Gemfile.rails60 +7 -0
- data/spec/gemfiles/Gemfile.rails61 +7 -0
- data/spec/integration/active_record/active_record_spec.rb +6 -3
- data/spec/integration/mongoid/mongoid_spec.rb +3 -1
- data/spec/integration/shared/at_time.rb +53 -0
- data/spec/integration/shared/between_dates.rb +99 -0
- data/spec/integration/shared/between_times.rb +27 -10
- data/spec/integration/shared/by_day.rb +24 -0
- data/spec/integration/shared/by_direction.rb +11 -57
- data/spec/integration/shared/index_scope_parameter.rb +111 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/unit/kernel_date_spec.rb +6 -6
- data/spec/unit/normalization_spec.rb +128 -49
- metadata +33 -21
- data/spec/gemfiles/Gemfile.master +0 -6
- data/spec/integration/shared/scope_parameter.rb +0 -73
data/README.md
CHANGED
@@ -8,12 +8,12 @@ ByStar (by_*) allows you easily and reliably query ActiveRecord and Mongoid obje
|
|
8
8
|
### Examples
|
9
9
|
|
10
10
|
```ruby
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
Post.by_year(2013) # all posts in 2013
|
12
|
+
Post.before(Date.today) # all posts for before today
|
13
|
+
Post.yesterday # all posts for yesterday
|
14
|
+
Post.between_times(Time.zone.now - 3.hours, # all posts in last 3 hours
|
15
|
+
Time.zone.now)
|
16
|
+
@post.next # next post after a given post
|
17
17
|
```
|
18
18
|
|
19
19
|
## Installation
|
@@ -21,7 +21,7 @@ ByStar (by_*) allows you easily and reliably query ActiveRecord and Mongoid obje
|
|
21
21
|
Install this gem by adding this to your Gemfile:
|
22
22
|
|
23
23
|
```ruby
|
24
|
-
gem 'by_star', git:
|
24
|
+
gem 'by_star', git: 'https://github.com/radar/by_star'
|
25
25
|
```
|
26
26
|
|
27
27
|
Then run `bundle install`
|
@@ -44,30 +44,36 @@ class MyModel
|
|
44
44
|
ByStar adds the following finder scopes (class methods) to your model to query time ranges.
|
45
45
|
These accept a `Date`, `Time`, or `DateTime` object as an argument, which defaults to `Time.zone.now` if not specified:
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
| Scope | Meaning |
|
48
|
+
| --- | --- |
|
49
|
+
| `between_times(start_time, end_time)` | Finds all records occurring between two given times. |
|
50
|
+
| `between_dates(start_date, end_date)` | Finds all records occurring between two given dates, from beginning of start_date until end of end_date. |
|
51
|
+
| `before(end_time)` | Finds all records occurring before the given time. |
|
52
|
+
| `after(start_time)` | Finds all records occurring after the given time. |
|
53
|
+
| `at_time(time)` | Finds all records occurring exactly at the given time, or which overlap the time in the case of "timespan"-type object (see below) |
|
50
54
|
|
51
|
-
`between_times` supports alternate argument forms:
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
55
|
+
`between_times` and `between_dates` supports alternate argument forms:
|
56
|
+
* `between_times(Range)`
|
57
|
+
* `between_times(Array)`
|
58
|
+
* `between_times(start_time, nil)` - same as `after(start_time)`
|
59
|
+
* `between_times(nil, end_time)` - same as `before(end_time)`
|
56
60
|
|
57
61
|
### Time Range Scopes
|
58
62
|
|
59
63
|
ByStar adds additional shortcut scopes based on commonly used time ranges.
|
60
64
|
See sections below for detailed argument usage of each:
|
61
65
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
| Scope | Meaning |
|
67
|
+
| --- | --- |
|
68
|
+
| `by_day` | Query by a given date. |
|
69
|
+
| `by_week` | Allows zero-based week value from 0 to 52. |
|
70
|
+
| `by_cweek` | Allows one-based week value from 1 to 53. |
|
71
|
+
| `by_weekend` | Saturday and Sunday only of the given week. |
|
72
|
+
| `by_fortnight` | A two-week period, with the first fortnight of the year beginning on 1st January. |
|
73
|
+
| `by_month` | Query by month. Allows integer arg, e.g. `11` for November. |
|
74
|
+
| `by_calendar_month` | Month as it appears on a calendar; days form previous/following months which are part of the first/last weeks of the given month. |
|
75
|
+
| `by_quarter` | 3-month intervals of the year. |
|
76
|
+
| `by_year` | Query by year. Allows integer arg, e.g. `2017`. |
|
71
77
|
|
72
78
|
### Relative Scopes
|
73
79
|
|
@@ -75,19 +81,21 @@ ByStar also adds scopes which are relative to the current time.
|
|
75
81
|
Note the `past_*` and `next_*` methods represent a time distance from current time (`Time.zone.now`),
|
76
82
|
and do not strictly end/begin evenly on a calendar week/month/year (unlike `by_*` methods which do.)
|
77
83
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
84
|
+
| Scope | Meaning |
|
85
|
+
| --- | --- |
|
86
|
+
| `today` | Finds all occurrences on today's date. |
|
87
|
+
| `yesterday` | Finds all occurrences on yesterday's date. |
|
88
|
+
| `tomorrow` | Finds all occurrences on tomorrow's date. |
|
89
|
+
| `past_day` | Prior 24-hour period from current time. |
|
90
|
+
| `past_week` | Prior 7-day period from current time. |
|
91
|
+
| `past_fortnight` | Prior 14-day period from current time. |
|
92
|
+
| `past_month` | Prior 30-day period from current time. |
|
93
|
+
| `past_year` | Prior 365-day period from current time. |
|
94
|
+
| `next_day` | Subsequent 24-hour period from current time. |
|
95
|
+
| `next_week` | Subsequent 7-day period from current time. |
|
96
|
+
| `next_fortnight` | Subsequent 14-day period from current time. |
|
97
|
+
| `next_month` | Subsequent 30-day period from current time. |
|
98
|
+
| `next_year` | Subsequent 365-day period from current time. |
|
91
99
|
|
92
100
|
### Superlative Finders
|
93
101
|
|
@@ -126,57 +134,42 @@ By default, ByStar assumes you will use the `created_at` field to query objects
|
|
126
134
|
You may specify an alternate field on all query methods as follows:
|
127
135
|
|
128
136
|
```ruby
|
129
|
-
|
137
|
+
Post.by_month("January", field: :updated_at)
|
130
138
|
```
|
131
139
|
|
132
140
|
Alternatively, you may set a default in your model using the `by_star_field` macro:
|
133
141
|
|
134
142
|
```ruby
|
135
|
-
|
136
|
-
|
137
|
-
|
143
|
+
class Post < ActiveRecord::Base
|
144
|
+
by_star_field :updated_at
|
145
|
+
end
|
138
146
|
```
|
139
147
|
|
140
148
|
### Scoping the Query
|
141
149
|
|
142
|
-
All ByStar methods (except `oldest`, `newest`, `previous`, `next`) return `ActiveRecord::Relation`
|
143
|
-
`Mongoid::Criteria`
|
150
|
+
All ByStar methods (except `oldest`, `newest`, `previous`, `next`) return an `ActiveRecord::Relation`
|
151
|
+
(or `Mongoid::Criteria`) which can be daisy-chained with other scopes/finder methods:
|
144
152
|
|
145
153
|
```ruby
|
146
|
-
|
147
|
-
|
154
|
+
Post.by_month.your_scope
|
155
|
+
Post.by_month(1).include(:tags).where("tags.name" => "ruby")
|
148
156
|
```
|
149
157
|
|
150
158
|
Want to count records? Simple:
|
151
159
|
|
152
160
|
```ruby
|
153
|
-
|
161
|
+
Post.by_month.count
|
154
162
|
```
|
155
163
|
|
156
|
-
###
|
164
|
+
### Timezone Handling
|
157
165
|
|
158
|
-
|
166
|
+
ByStar date-range finders will use value of `Time.zone` to evaluate the args.
|
167
|
+
This may cause unexpected behavior when use Time values in timezones other than `Time.zone`.
|
159
168
|
|
160
169
|
```ruby
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
This is particularly useful for `oldest`, `newest`, `previous`, `next` which return a model instance rather than
|
166
|
-
a Relation and hence cannot be daisy-chained with other scopes.
|
167
|
-
|
168
|
-
`previous` and `next` support a special feature that the `:scope` option may take the subject record as an argument:
|
169
|
-
|
170
|
-
```ruby
|
171
|
-
@post.next(scope: ->(record){ where(category: record.category) })
|
172
|
-
```
|
173
|
-
|
174
|
-
You may also set a default scope in the `by_star_field` macro. (It is recommended this be a Proc):
|
175
|
-
|
176
|
-
```ruby
|
177
|
-
class Post < ActiveRecord::Base
|
178
|
-
by_star_field scope: ->{ where(category: 'blog') }
|
179
|
-
end
|
170
|
+
Time.zone = 'Australia/Sydney'
|
171
|
+
Post.by_day('2020-04-05 18:00:00 EST')
|
172
|
+
#=> Returns Apr 6th, 0:00 until Apr 6th, 23:59 in Sydney timezone.
|
180
173
|
```
|
181
174
|
|
182
175
|
### `:offset` Option
|
@@ -186,14 +179,16 @@ This is useful in cases where the daily cycle occurs at a time other than midnig
|
|
186
179
|
|
187
180
|
For example, if you'd like to find all Posts from 9:00 on 2014-03-05 until 8:59:59.999 on 2014-03-06, you can do:
|
188
181
|
|
189
|
-
|
182
|
+
```ruby
|
183
|
+
Post.by_day('2014-03-05', offset: 9.hours)
|
184
|
+
```
|
190
185
|
|
191
|
-
|
186
|
+
**Note:** When passing `offset` in date finders, it will set the hour, minute, and second on the queried date in order to properly handle DST transitions. Example:
|
192
187
|
|
193
188
|
```ruby
|
194
|
-
|
195
|
-
|
196
|
-
|
189
|
+
Time.zone = 'Australia/Sydney'
|
190
|
+
Post.by_day('2020-04-05', offset: 9.hours)
|
191
|
+
#=> Returns Apr 5th, 09:00 until Apr 6th, 08:59
|
197
192
|
```
|
198
193
|
|
199
194
|
### Timespan Objects
|
@@ -201,25 +196,39 @@ You may also set a offset scope in the `by_star_field` macro:
|
|
201
196
|
If your object has both a start and end time, you may pass both params to `by_star_field`:
|
202
197
|
|
203
198
|
```ruby
|
204
|
-
|
199
|
+
by_star_field :start_time, :end_time
|
205
200
|
```
|
206
201
|
|
207
202
|
By default, ByStar queries will return all objects whose range has any overlap within the desired period (permissive):
|
208
203
|
|
209
204
|
```ruby
|
210
|
-
|
211
|
-
|
205
|
+
MultiDayEvent.by_month("January")
|
206
|
+
#=> returns MultiDayEvents that overlap in January,
|
207
|
+
# even if they start in December and/or end in February
|
208
|
+
```
|
209
|
+
|
210
|
+
### Timespan Objects: `#at_time`
|
211
|
+
|
212
|
+
To find all instances of a timespan object which contain a specific time:
|
213
|
+
|
214
|
+
```ruby
|
215
|
+
Post.at_time(time)
|
212
216
|
```
|
213
217
|
|
218
|
+
This can be useful to find all currently active instances. Note that object instances which start
|
219
|
+
exactly at the given `time` will be included in the result, but instances that end exactly at the given
|
220
|
+
`time` will not be.
|
221
|
+
|
214
222
|
### Timespan Objects: `:strict` Option
|
215
223
|
|
216
224
|
If you'd like to confine results to only those both starting and ending within the given range, use the `:strict` option:
|
217
225
|
|
218
226
|
```ruby
|
219
|
-
|
227
|
+
MultiDayEvent.by_month("January", :strict => true)
|
228
|
+
#=> returns MultiDayEvents that both start AND end in January
|
220
229
|
```
|
221
230
|
|
222
|
-
### Timespan Objects: Database Indexing and `:
|
231
|
+
### Timespan Objects: Database Indexing and `:index_scope` Option
|
223
232
|
|
224
233
|
In order to ensure query performance on large dataset, you must add an index to the query field (e.g. "created_at") be indexed. ByStar does **not** define indexes automatically.
|
225
234
|
|
@@ -228,14 +237,40 @@ If we use a single-sided query, the database will iterate through all items eith
|
|
228
237
|
This poses a challenge for timespan-type objects which have two fields, i.e. `start_time` and `end_time`.
|
229
238
|
There are two cases to consider:
|
230
239
|
|
231
|
-
1) Timespan with `:strict` option, e.g.
|
240
|
+
1) Timespan with `:strict` option, e.g. `start_time >= X and end_time <= Y`.
|
232
241
|
|
233
|
-
Given that this gem requires start_time >= end_time
|
242
|
+
Given that this gem requires `start_time >= end_time`, we add the converse constraint `start_time <= Y and end_time >= X`
|
243
|
+
to ensure both fields are double-sided, i.e. an index can be used on either field.
|
234
244
|
|
235
245
|
2) Timespan without `:strict` option, e.g. "start_time < Y and end_time > X".
|
236
246
|
|
237
|
-
|
247
|
+
Here we need to add a condition `start_time >= X` to ensure `start_time` is bounded on both sides.
|
248
|
+
To achieve this, we allow an `:index_scope` option which is the minimum "strict" bound on the querying range,
|
249
|
+
in other words, it is an assumption about the maximum timespan of objects.
|
250
|
+
|
251
|
+
`:index_scope` supports multiple value types:
|
252
|
+
|
253
|
+
| `:index_scope` Value | Meaning |
|
254
|
+
| --- | --- |
|
255
|
+
| `nil` or `false` | No constraint set; query will be one-sided (default, but not recommended) |
|
256
|
+
| `Date` or `Time`, etc. | A fixed point in time |
|
257
|
+
| `ActiveSupport::Duration` (e.g. `1.month`) | The duration value will be subtracted from the start of the range. In other words, a value of `1.month` would imply the longest possible object in the database is no longer than `1.month`. |
|
258
|
+
| `Numeric` | Will be converted to seconds, then handled the same as `ActiveSupport::Duration` |
|
259
|
+
| `:beginning_of_day` (`Symbol` literal) |
|
260
|
+
| `Proc<Range, Hash(options)>` | A proc which evaluates to one of the above types. Args are `(start_time, end_time, options)` |
|
261
|
+
|
262
|
+
An example settings of `:index_scope`:
|
238
263
|
|
264
|
+
```
|
265
|
+
# The maximum possible object length is 5 hours.
|
266
|
+
by_star index_scope: 5.hours
|
267
|
+
|
268
|
+
# Objects are guaranteed to start within the same month, with some offset.
|
269
|
+
by_star index_scope: ->(start_time, end_time, options){ start_time.beginning_of_month + (options[:offset] || 0) }
|
270
|
+
|
271
|
+
# The maximum possible object length half the range being queried.
|
272
|
+
by_star index_scope: ->(start_time, end_time, options){ ((start_time - end_time)*0.5).seconds }
|
273
|
+
```
|
239
274
|
|
240
275
|
### Chronic Support
|
241
276
|
|
@@ -244,7 +279,6 @@ strings in all ByStar finder methods. Otherwise, the Ruby `Time.parse` kernel me
|
|
244
279
|
|
245
280
|
As of ByStar 2.2.0, you must explicitly include `gem 'chronic'` into your Gemfile in order to use Chronic.
|
246
281
|
|
247
|
-
|
248
282
|
## Advanced Usage
|
249
283
|
|
250
284
|
### between_times
|
@@ -252,41 +286,43 @@ As of ByStar 2.2.0, you must explicitly include `gem 'chronic'` into your Gemfil
|
|
252
286
|
To find records between two times:
|
253
287
|
|
254
288
|
```ruby
|
255
|
-
|
289
|
+
Post.between_times(time1, time2)
|
256
290
|
```
|
257
291
|
|
258
292
|
You use a Range like so:
|
259
293
|
|
260
294
|
```ruby
|
261
|
-
|
295
|
+
Post.between_times(time1..time2)
|
262
296
|
```
|
263
297
|
|
264
298
|
Also works with dates - WARNING: there are currently some caveats see [Issue #49](https://github.com/radar/by_star/issues/49):
|
265
299
|
|
266
300
|
```ruby
|
267
|
-
|
301
|
+
Post.between_times(date1, date2)
|
268
302
|
```
|
269
303
|
|
304
|
+
It will query records from `date1` (00:00:00 Hrs) until `date2` (23:59:59 Hrs).
|
305
|
+
|
270
306
|
### before and after
|
271
307
|
|
272
308
|
To find all posts before / after the current time:
|
273
309
|
|
274
310
|
```ruby
|
275
|
-
|
276
|
-
|
311
|
+
Post.before
|
312
|
+
Post.after
|
277
313
|
```
|
278
314
|
|
279
315
|
To find all posts before certain time or date:
|
280
316
|
|
281
317
|
```ruby
|
282
|
-
|
283
|
-
|
318
|
+
Post.before(Date.today + 2)
|
319
|
+
Post.after(Time.now + 5.days)
|
284
320
|
```
|
285
321
|
|
286
322
|
You can also pass a string:
|
287
323
|
|
288
324
|
```ruby
|
289
|
-
|
325
|
+
Post.before("next tuesday")
|
290
326
|
```
|
291
327
|
|
292
328
|
For Time-Range type objects, only the start time is considered for `before` and `after`.
|
@@ -296,15 +332,15 @@ For Time-Range type objects, only the start time is considered for `before` and
|
|
296
332
|
To find the prior/subsequent record to a model instance, `previous`/`next` on it:
|
297
333
|
|
298
334
|
```ruby
|
299
|
-
|
300
|
-
|
335
|
+
Post.last.previous
|
336
|
+
Post.first.next
|
301
337
|
```
|
302
338
|
|
303
339
|
You can specify a field also:
|
304
340
|
|
305
341
|
```ruby
|
306
|
-
|
307
|
-
|
342
|
+
Post.last.previous(field: "published_at")
|
343
|
+
Post.first.next(field: "published_at")
|
308
344
|
```
|
309
345
|
|
310
346
|
For Time-Range type objects, only the start time is considered for `previous` and `next`.
|
@@ -314,19 +350,19 @@ For Time-Range type objects, only the start time is considered for `previous` an
|
|
314
350
|
To find records from the current year, simply call the method without any arguments:
|
315
351
|
|
316
352
|
```ruby
|
317
|
-
|
353
|
+
Post.by_year
|
318
354
|
```
|
319
355
|
|
320
356
|
To find records based on a year you can pass it a two or four digit number:
|
321
357
|
|
322
358
|
```ruby
|
323
|
-
|
359
|
+
Post.by_year(09)
|
324
360
|
```
|
325
361
|
|
326
362
|
This will return all posts in 2009, whereas:
|
327
363
|
|
328
364
|
```ruby
|
329
|
-
|
365
|
+
Post.by_year(99)
|
330
366
|
```
|
331
367
|
|
332
368
|
will return all the posts in the year 1999.
|
@@ -334,8 +370,8 @@ will return all the posts in the year 1999.
|
|
334
370
|
You can also specify the full year:
|
335
371
|
|
336
372
|
```ruby
|
337
|
-
|
338
|
-
|
373
|
+
Post.by_year(2009)
|
374
|
+
Post.by_year(1999)
|
339
375
|
```
|
340
376
|
|
341
377
|
### by_month
|
@@ -343,7 +379,7 @@ You can also specify the full year:
|
|
343
379
|
If you know the number of the month you want:
|
344
380
|
|
345
381
|
```ruby
|
346
|
-
|
382
|
+
Post.by_month(1)
|
347
383
|
```
|
348
384
|
|
349
385
|
This will return all posts in the first month (January) of the current year.
|
@@ -351,7 +387,7 @@ This will return all posts in the first month (January) of the current year.
|
|
351
387
|
If you like being verbose:
|
352
388
|
|
353
389
|
```ruby
|
354
|
-
|
390
|
+
Post.by_month("January")
|
355
391
|
```
|
356
392
|
|
357
393
|
This will return all posts created in January of the current year.
|
@@ -359,13 +395,13 @@ This will return all posts created in January of the current year.
|
|
359
395
|
If you want to find all posts in January of last year just do
|
360
396
|
|
361
397
|
```ruby
|
362
|
-
|
398
|
+
Post.by_month(1, year: 2007)
|
363
399
|
```
|
364
400
|
|
365
401
|
or
|
366
402
|
|
367
403
|
```ruby
|
368
|
-
|
404
|
+
Post.by_month("January", year: 2007)
|
369
405
|
```
|
370
406
|
|
371
407
|
This will perform a find using the column you've specified.
|
@@ -373,7 +409,7 @@ This will perform a find using the column you've specified.
|
|
373
409
|
If you have a Time object you can use it to find the posts:
|
374
410
|
|
375
411
|
```ruby
|
376
|
-
|
412
|
+
Post.by_month(Time.local(2012, 11, 24))
|
377
413
|
```
|
378
414
|
|
379
415
|
This will find all the posts in November 2012.
|
@@ -383,7 +419,7 @@ This will find all the posts in November 2012.
|
|
383
419
|
Finds records for a given month as shown on a calendar. Includes all the results of `by_month`, plus any results which fall in the same week as the first and last of the month. Useful for working with UI calendars which show rows of weeks.
|
384
420
|
|
385
421
|
```ruby
|
386
|
-
|
422
|
+
Post.by_calendar_month
|
387
423
|
```
|
388
424
|
|
389
425
|
Parameter behavior is otherwise the same as `by_month`. Also, `:start_day` option is supported to specify the start day of the week (`:monday`, `:tuesday`, etc.)
|
@@ -395,25 +431,25 @@ Fortnight numbering starts at 0. The beginning of a fortnight is Monday, 12am.
|
|
395
431
|
To find records from the current fortnight:
|
396
432
|
|
397
433
|
```ruby
|
398
|
-
|
434
|
+
Post.by_fortnight
|
399
435
|
```
|
400
436
|
|
401
437
|
To find records based on a fortnight, you can pass in a number (representing the fortnight number) or a time object:
|
402
438
|
|
403
439
|
```ruby
|
404
|
-
|
440
|
+
Post.by_fortnight(18)
|
405
441
|
```
|
406
442
|
|
407
443
|
This will return all posts in the 18th fortnight of the current year.
|
408
444
|
|
409
445
|
```ruby
|
410
|
-
|
446
|
+
Post.by_fortnight(18, year: 2012)
|
411
447
|
```
|
412
448
|
|
413
449
|
This will return all posts in the 18th fortnight week of 2012.
|
414
450
|
|
415
451
|
```ruby
|
416
|
-
|
452
|
+
Post.by_fortnight(Time.local(2012,1,1))
|
417
453
|
```
|
418
454
|
|
419
455
|
This will return all posts from the first fortnight of 2012.
|
@@ -425,29 +461,29 @@ Week numbering starts at 0, and cweek numbering starts at 1 (same as `Date#cweek
|
|
425
461
|
To find records from the current week:
|
426
462
|
|
427
463
|
```ruby
|
428
|
-
|
429
|
-
|
464
|
+
Post.by_week
|
465
|
+
Post.by_cweek # same result
|
430
466
|
```
|
431
467
|
|
432
468
|
This will return all posts in the 37th week of the current year (remember week numbering starts at 0):
|
433
469
|
|
434
470
|
```ruby
|
435
|
-
|
436
|
-
|
471
|
+
Post.by_week(36)
|
472
|
+
Post.by_cweek(37) # same result
|
437
473
|
```
|
438
474
|
|
439
475
|
This will return all posts in the 37th week of 2012:
|
440
476
|
|
441
477
|
```ruby
|
442
|
-
|
443
|
-
|
478
|
+
Post.by_week(36, year: 2012)
|
479
|
+
Post.by_cweek(37, year: 2012) # same result
|
444
480
|
```
|
445
481
|
|
446
482
|
This will return all posts in the week which contains Jan 1, 2012:
|
447
483
|
|
448
484
|
```ruby
|
449
|
-
|
450
|
-
|
485
|
+
Post.by_week(Time.local(2012,1,1))
|
486
|
+
Post.by_cweek(Time.local(2012,1,1)) # same result
|
451
487
|
```
|
452
488
|
|
453
489
|
You may pass in a `:start_day` option (`:monday`, `:tuesday`, etc.) to specify the starting day of the week. This may also be configured in Rails.
|
@@ -457,7 +493,7 @@ You may pass in a `:start_day` option (`:monday`, `:tuesday`, etc.) to specify t
|
|
457
493
|
If the time passed in (or the time now is a weekend) it will return posts from 0:00 Saturday to 23:59:59 Sunday. If the time is a week day, it will show all posts for the coming weekend.
|
458
494
|
|
459
495
|
```ruby
|
460
|
-
|
496
|
+
Post.by_weekend(Time.now)
|
461
497
|
```
|
462
498
|
|
463
499
|
### by_day and today
|
@@ -465,20 +501,20 @@ If the time passed in (or the time now is a weekend) it will return posts from 0
|
|
465
501
|
To find records for today:
|
466
502
|
|
467
503
|
```ruby
|
468
|
-
|
469
|
-
|
504
|
+
Post.by_day
|
505
|
+
Post.today
|
470
506
|
```
|
471
507
|
|
472
508
|
To find records for a certain day:
|
473
509
|
|
474
510
|
```ruby
|
475
|
-
|
511
|
+
Post.by_day(Time.local(2012, 1, 1))
|
476
512
|
```
|
477
513
|
|
478
514
|
You can also pass a string:
|
479
515
|
|
480
516
|
```ruby
|
481
|
-
|
517
|
+
Post.by_day("next tuesday")
|
482
518
|
```
|
483
519
|
|
484
520
|
This will return all posts for the given day.
|
@@ -490,42 +526,41 @@ Finds records by 3-month quarterly period of year. Quarter numbering starts at 1
|
|
490
526
|
To find records from the current quarter:
|
491
527
|
|
492
528
|
```ruby
|
493
|
-
|
529
|
+
Post.by_quarter
|
494
530
|
```
|
495
531
|
|
496
532
|
To find records based on a quarter, you can pass in a number (representing the quarter number) or a time object:
|
497
533
|
|
498
534
|
```ruby
|
499
|
-
|
535
|
+
Post.by_quarter(4)
|
500
536
|
```
|
501
537
|
|
502
538
|
This will return all posts in the 4th quarter of the current year.
|
503
539
|
|
504
540
|
```ruby
|
505
|
-
|
541
|
+
Post.by_quarter(2, year: 2012)
|
506
542
|
```
|
507
543
|
|
508
544
|
This will return all posts in the 2nd quarter of 2012.
|
509
545
|
|
510
546
|
```ruby
|
511
|
-
|
547
|
+
Post.by_week(Time.local(2012,1,1))
|
512
548
|
```
|
513
549
|
|
514
550
|
This will return all posts from the first quarter of 2012.
|
515
551
|
|
516
|
-
|
517
552
|
## Version Support
|
518
553
|
|
519
554
|
ByStar is tested against the following versions:
|
520
555
|
|
521
|
-
* Ruby
|
522
|
-
* Rails/ActiveRecord 3.
|
523
|
-
* Mongoid 3.
|
556
|
+
* Ruby 2.0.0+
|
557
|
+
* Rails/ActiveRecord 3.2+
|
558
|
+
* Mongoid 3.1+
|
524
559
|
|
525
560
|
Note that ByStar automatically adds the following version compatibility shims:
|
526
561
|
|
527
|
-
* ActiveSupport 3.x: `Date#
|
528
|
-
* Mongoid 3.x: Adds
|
562
|
+
* ActiveSupport 3.x: Add `Time/Date/DateTime#in_time_zone` (as an alias to `#to_time_in_current_zone`) for compatibility with Rails 4+.
|
563
|
+
* Mongoid 3.x: Adds `Criteria#reorder` method from Mongoid 4.
|
529
564
|
|
530
565
|
|
531
566
|
## Testing
|
@@ -534,11 +569,15 @@ Note that ByStar automatically adds the following version compatibility shims:
|
|
534
569
|
|
535
570
|
Specify a database by supplying a `DB` environmental variable:
|
536
571
|
|
537
|
-
|
572
|
+
```bash
|
573
|
+
bundle exec rake spec DB=sqlite
|
574
|
+
```
|
538
575
|
|
539
576
|
You can also take an ORM-specific test task for a ride:
|
540
577
|
|
541
|
-
|
578
|
+
```bash
|
579
|
+
bundle exec rake spec:active_record
|
580
|
+
```
|
542
581
|
|
543
582
|
Have an Active Record or Mongoid version in mind? Set the environment variables
|
544
583
|
`ACTIVE_RECORD_VERSION` and `MONGOID_VERSION` to a version of your choice. A
|
data/UPGRADING
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
Upgrading ByStar
|
2
2
|
----------------
|
3
3
|
|
4
|
-
*
|
5
|
-
however it is still supported. If you would like to use Chronic with ByStar, please explicitly
|
6
|
-
include `gem chronic` into your Gemfile.
|
4
|
+
* As of version 4.0.0, ByStar changes the way it handles `Date` arg to the `#between_times` method. If a `Date` is given as the second (end) arg, the query will use `Date.end_of_day` to include all time values which fall inside that date.
|
data/by_star.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
|
15
15
|
s.post_install_message = File.read('UPGRADING') if File.exists?('UPGRADING')
|
16
16
|
|
17
|
-
s.add_dependency "activesupport", "
|
17
|
+
s.add_dependency "activesupport", ">= 3.2.0"
|
18
18
|
|
19
19
|
s.add_development_dependency "chronic"
|
20
20
|
s.add_development_dependency "bundler"
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_development_dependency "activerecord"
|
23
23
|
s.add_development_dependency "mongoid"
|
24
24
|
s.add_development_dependency "pg"
|
25
|
-
s.add_development_dependency "mysql2"
|
25
|
+
s.add_development_dependency "mysql2"
|
26
26
|
s.add_development_dependency "rspec-rails", "~> 3.1"
|
27
27
|
s.add_development_dependency "timecop", "~> 0.3"
|
28
28
|
s.add_development_dependency "pry"
|