season 0.1 → 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 +4 -4
- data/README.md +21 -37
- data/lib/season.rb +30 -1
- data/lib/season/configuration.rb +2 -1
- data/lib/season/{active_record/scopes.rb → legacy.rb} +2 -3
- data/lib/season/query_builder.rb +26 -0
- data/lib/season/scope_builder.rb +34 -0
- data/lib/season/version.rb +1 -1
- data/season.gemspec +2 -2
- data/spec/scopes_spec.rb +54 -0
- metadata +9 -9
- data/spec/active_record/scopes_spec.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 899d9f7e0405d00eb51394bcb984c496ed0b06fc
|
4
|
+
data.tar.gz: 91138329eec2efd1ee082eb6e30dc284a418047f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af150a59bfa9de34841468175840cd0edfa130c38232dcd934fa04a6321ccc28550d45ca0c680323e3a55b3cc4b062bf8d22d15c8fa703caeaa77861ca2d1fdf
|
7
|
+
data.tar.gz: 6d83a87905bf1941d0108d245f26e9a17c1a9d9c2fa512ed12b4e45fb0862ebef1c389201d71584c3e5927718331c50974d0d047fdbb0af6a4db389d14e0286a
|
data/README.md
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
# Season
|
2
2
|
[](http://badge.fury.io/rb/season) [](https://codeclimate.com/github/joaodiogocosta/season) [](https://travis-ci.org/joaodiogocosta/season)
|
3
3
|
|
4
|
-
Season
|
4
|
+
Season automatically creates scopes for your models' datetime columns.
|
5
|
+
How many times have you done ugly things like `where("users.created_at" > ?", some_date)`? If you ever built a REST API with endpoints that return a list of records, I'm sure you've done plenty of this. And that's why Season exists.
|
5
6
|
|
6
7
|
## Installation
|
7
8
|
|
8
9
|
Add this line to your application's Gemfile:
|
9
10
|
|
10
11
|
```ruby
|
11
|
-
gem 'season', '~> 0.
|
12
|
+
gem 'season', '~> 0.2'
|
12
13
|
```
|
13
14
|
|
14
15
|
And then execute:
|
@@ -25,28 +26,31 @@ In this first version Season only supports ActiveRecord, but we plan to also sup
|
|
25
26
|
|
26
27
|
## Usage
|
27
28
|
|
28
|
-
Season
|
29
|
-
|
30
|
-
Right now, Season gives you the following helper methods:
|
29
|
+
To use Season scopes just append `_before`, `_after` or `_between` to your datetime column names and pass the arguments accordingly. See this:
|
31
30
|
|
31
|
+
First, include Season in your model(s):
|
32
32
|
```ruby
|
33
|
-
# Include it in your models
|
34
|
-
|
35
33
|
class User < ActiveRecord::Base
|
36
|
-
include Season
|
34
|
+
include Season
|
37
35
|
...
|
38
36
|
end
|
37
|
+
```
|
38
|
+
|
39
|
+
Now, considering that our `User` class has three datetime columns named `:created_at`, `:updated_at` and `:confirmed_at`, the following scopes will be automatically available:
|
40
|
+
```ruby
|
41
|
+
# * Time/DateTime/String instances are allowed as arguments.
|
39
42
|
|
40
|
-
|
41
|
-
|
43
|
+
User.created_at_before(Time.now)
|
44
|
+
User.created_at_after(DateTime.now)
|
45
|
+
User.created_at_between(Time.now - 1.week, '31-01-2015')
|
42
46
|
|
43
|
-
User.
|
44
|
-
User.
|
45
|
-
User.
|
47
|
+
User.updated_at_before(DateTime.now)
|
48
|
+
User.updated_at_after('01-01-2015')
|
49
|
+
User.updated_at_between(Time.now - 1.week, Time.now)
|
46
50
|
|
47
|
-
User.
|
48
|
-
User.
|
49
|
-
User.
|
51
|
+
User.confirmed_at_before('01-01-2015')
|
52
|
+
User.confirmed_at_after(DateTime.now)
|
53
|
+
User.confirmed_at_between(Time.now - 1.year, Time.now - 1.week)
|
50
54
|
```
|
51
55
|
|
52
56
|
They are chainable, so you can also do things like this:
|
@@ -55,33 +59,13 @@ User.where(id: [1, 2, 3]).created_before(Time.now)
|
|
55
59
|
User.updated_after('01-01-2015').order(created_at: :asc)
|
56
60
|
```
|
57
61
|
|
58
|
-
|
59
|
-
## Configuration
|
60
|
-
|
61
|
-
The scopes are not included by default in your models. To use them you need to include it yourself:
|
62
|
-
|
63
|
-
```ruby
|
64
|
-
class User < ActiveRecord::Base
|
65
|
-
include Season::Scopes
|
66
|
-
...
|
67
|
-
end
|
68
|
-
```
|
69
|
-
|
70
|
-
If you want them to be available on all of your models by default, add the following code within an initializer - `config/initializers/season.rb`:
|
71
|
-
|
72
|
-
```ruby
|
73
|
-
Season.configure do |config|
|
74
|
-
config.include_by_default = true
|
75
|
-
end
|
76
|
-
```
|
77
|
-
|
78
62
|
## To Do
|
79
63
|
|
80
64
|
- Even more tests
|
81
65
|
- Support other ORMs (Mongoid, 'insert-more-here')
|
82
66
|
- Add Error Handling
|
83
67
|
- Add helpers for instances (like `User.first.created_before?('01-02-2015')`)
|
84
|
-
-
|
68
|
+
- Add support for queries with joins
|
85
69
|
|
86
70
|
## Contributing
|
87
71
|
|
data/lib/season.rb
CHANGED
@@ -1,3 +1,32 @@
|
|
1
1
|
require "season/version"
|
2
2
|
require "season/configuration"
|
3
|
-
require "season/
|
3
|
+
require "season/legacy"
|
4
|
+
require "season/scope_builder"
|
5
|
+
require "season/query_builder"
|
6
|
+
|
7
|
+
module Season
|
8
|
+
|
9
|
+
QUERY_VERBS = ['before', 'after', 'between']
|
10
|
+
|
11
|
+
def self.included(base)
|
12
|
+
base.extend(ClassMethods)
|
13
|
+
|
14
|
+
mb = ScopeBuilder.new(base)
|
15
|
+
|
16
|
+
base.class_eval do
|
17
|
+
# DEFINE SCOPES DINAMICALLY
|
18
|
+
base.datetime_column_names.each do |column_name|
|
19
|
+
QUERY_VERBS.each do |query_verb|
|
20
|
+
mb.build(table_name, column_name, query_verb)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
def datetime_column_names
|
28
|
+
columns.map { |c| c.name if c.type == :datetime }.compact
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
data/lib/season/configuration.rb
CHANGED
@@ -23,7 +23,8 @@ module Season
|
|
23
23
|
|
24
24
|
def self.auto_include_scopes
|
25
25
|
if configuration.include_by_default
|
26
|
-
|
26
|
+
warn "[DEPRECATED] Include season scopes by default is deprecated and will be removed before v0.5 - See https://github.com/joaodiogocosta/season for more"
|
27
|
+
ActiveRecord::Base.send(:include, Season::Legacy) if defined? ActiveRecord
|
27
28
|
end
|
28
29
|
end
|
29
30
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Season
|
2
|
+
class QueryBuilder
|
3
|
+
|
4
|
+
def initialize(adapter_class_name)
|
5
|
+
@adapter_class_name = adapter_class_name
|
6
|
+
end
|
7
|
+
|
8
|
+
def build(table_name, column_name, query_verb)
|
9
|
+
self.send("#{@adapter_class_name}_#{query_verb}", table_name, column_name)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def active_record_before(table_name, column_name)
|
15
|
+
"where(" + "\"#{table_name}.#{column_name} < ?\"" + ", *args)"
|
16
|
+
end
|
17
|
+
|
18
|
+
def active_record_between(table_name, column_name)
|
19
|
+
"where(" + "\"#{table_name}.#{column_name} > ? AND #{table_name}.#{column_name} < ?\"" + ", *args)"
|
20
|
+
end
|
21
|
+
|
22
|
+
def active_record_after(table_name, column_name)
|
23
|
+
"where(" + "\"#{table_name}.#{column_name} > ?\"" + ", *args)"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Season
|
2
|
+
class ScopeBuilder
|
3
|
+
|
4
|
+
def initialize(klass)
|
5
|
+
@klass = klass
|
6
|
+
@query_builder = QueryBuilder.new(adapter_class_name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def build(table_name, column_name, query_verb)
|
10
|
+
unless method_exists?(column_name)
|
11
|
+
query_str = @query_builder.build(table_name, column_name, query_verb)
|
12
|
+
|
13
|
+
@klass.define_singleton_method "#{column_name}_#{query_verb}" do |*args|
|
14
|
+
eval(query_str)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def method_exists?(column_name)
|
22
|
+
defined? @klass.column_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def adapter_class_name
|
26
|
+
return 'active_record' if @klass < ActiveRecord::Base
|
27
|
+
raise "Database adapter not supported."
|
28
|
+
end
|
29
|
+
|
30
|
+
# def remove_old_suffix(text)
|
31
|
+
# text.sub(/(#{POPULAR_SUFFIXES.join('|')})$/, '') || text
|
32
|
+
# end
|
33
|
+
end
|
34
|
+
end
|
data/lib/season/version.rb
CHANGED
data/season.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Season::VERSION
|
9
9
|
spec.authors = ["Joao Diogo Costa"]
|
10
10
|
spec.email = ["jdscosta91@gmail.com"]
|
11
|
-
spec.summary = %q{Season
|
12
|
-
spec.description = %q{Season
|
11
|
+
spec.summary = %q{Season automatically creates scopes for your models' datetime columns.}
|
12
|
+
spec.description = %q{Season automatically creates scopes for your models' datetime columns.}
|
13
13
|
spec.homepage = "https://github.com/joaodiogocosta/season"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/spec/scopes_spec.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
silence_warnings do
|
5
|
+
ActiveRecord::Migration.verbose = false
|
6
|
+
ActiveRecord::Base.logger = Logger.new(nil)
|
7
|
+
ActiveRecord::Base.establish_connection(
|
8
|
+
adapter: 'sqlite3', database: ':memory:')
|
9
|
+
end
|
10
|
+
|
11
|
+
ActiveRecord::Base.connection.instance_eval do
|
12
|
+
create_table :users do |t|
|
13
|
+
t.datetime :created_at
|
14
|
+
t.datetime :updated_at
|
15
|
+
t.timestamp :confirmed_at
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Season.configure do |config|
|
20
|
+
config.include_by_default = true
|
21
|
+
end
|
22
|
+
|
23
|
+
class User < ActiveRecord::Base
|
24
|
+
include Season
|
25
|
+
end
|
26
|
+
|
27
|
+
RSpec.describe Season do
|
28
|
+
subject { User }
|
29
|
+
|
30
|
+
it 'has scopes to datetime columns of datetime type' do
|
31
|
+
expect(subject).to respond_to(:created_at_before, :created_at_after)
|
32
|
+
.with(1).argument
|
33
|
+
expect(subject).to respond_to(:created_at_between).with(2).arguments
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'has scopes to datetime columns of timestamp type' do
|
37
|
+
expect(subject).to respond_to(:confirmed_at_before, :confirmed_at_after)
|
38
|
+
.with(1).argument
|
39
|
+
expect(subject).to respond_to(:confirmed_at_between).with(2).arguments
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'has legacy scopes' do
|
43
|
+
expect(subject).to respond_to(:created_before, :created_after)
|
44
|
+
.with(1).argument
|
45
|
+
expect(subject).to respond_to(:created_between).with(2).arguments
|
46
|
+
expect(subject).to respond_to(:updated_before, :updated_after)
|
47
|
+
.with(1).argument
|
48
|
+
expect(subject).to respond_to(:updated_between).with(2).arguments
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'has legacy scopes' do
|
52
|
+
expect(subject.created_at_before(Time.now)).to eq([])
|
53
|
+
end
|
54
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: season
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joao Diogo Costa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -108,8 +108,7 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '1.3'
|
111
|
-
description: Season
|
112
|
-
of time in an easier way.
|
111
|
+
description: Season automatically creates scopes for your models' datetime columns.
|
113
112
|
email:
|
114
113
|
- jdscosta91@gmail.com
|
115
114
|
executables: []
|
@@ -125,11 +124,13 @@ files:
|
|
125
124
|
- README.md
|
126
125
|
- Rakefile
|
127
126
|
- lib/season.rb
|
128
|
-
- lib/season/active_record/scopes.rb
|
129
127
|
- lib/season/configuration.rb
|
128
|
+
- lib/season/legacy.rb
|
129
|
+
- lib/season/query_builder.rb
|
130
|
+
- lib/season/scope_builder.rb
|
130
131
|
- lib/season/version.rb
|
131
132
|
- season.gemspec
|
132
|
-
- spec/
|
133
|
+
- spec/scopes_spec.rb
|
133
134
|
- spec/spec_helper.rb
|
134
135
|
homepage: https://github.com/joaodiogocosta/season
|
135
136
|
licenses:
|
@@ -154,8 +155,7 @@ rubyforge_project:
|
|
154
155
|
rubygems_version: 2.4.3
|
155
156
|
signing_key:
|
156
157
|
specification_version: 4
|
157
|
-
summary: Season
|
158
|
-
in an easier way.
|
158
|
+
summary: Season automatically creates scopes for your models' datetime columns.
|
159
159
|
test_files:
|
160
|
-
- spec/
|
160
|
+
- spec/scopes_spec.rb
|
161
161
|
- spec/spec_helper.rb
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'active_record'
|
3
|
-
require 'season/active_record/scopes'
|
4
|
-
|
5
|
-
silence_warnings do
|
6
|
-
ActiveRecord::Migration.verbose = false
|
7
|
-
ActiveRecord::Base.logger = Logger.new(nil)
|
8
|
-
ActiveRecord::Base.establish_connection(
|
9
|
-
adapter: 'sqlite3', database: ':memory:')
|
10
|
-
end
|
11
|
-
|
12
|
-
ActiveRecord::Base.connection.instance_eval do
|
13
|
-
create_table :users do |t|
|
14
|
-
t.timestamps null: true
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class User < ActiveRecord::Base
|
19
|
-
include Season::Scopes
|
20
|
-
end
|
21
|
-
|
22
|
-
RSpec.describe Season::Scopes do
|
23
|
-
subject { User }
|
24
|
-
|
25
|
-
describe 'class methods' do
|
26
|
-
describe 'with default timestamps' do
|
27
|
-
it 'responds to created_(before/after/between)' do
|
28
|
-
expect(subject).to respond_to(:created_before, :created_after)
|
29
|
-
.with(1).argument
|
30
|
-
expect(subject).to respond_to(:created_between).with(2).arguments
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'responds to updated_(before/after/between)' do
|
34
|
-
expect(subject).to respond_to(:updated_before, :updated_after)
|
35
|
-
.with(1).argument
|
36
|
-
expect(subject).to respond_to(:updated_between).with(2).arguments
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|