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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 79b28b9578876f09d5400f07f274fa4b09403f73
4
- data.tar.gz: f92588ed36959b02592fdd52a654aa77651da231
3
+ metadata.gz: 899d9f7e0405d00eb51394bcb984c496ed0b06fc
4
+ data.tar.gz: 91138329eec2efd1ee082eb6e30dc284a418047f
5
5
  SHA512:
6
- metadata.gz: 97af23dc94be0015526dfee136ce23b3d14e163472091116efc9240560369ecf635b12150ecced3448a8bb60a4447f7e3312cbc5253a01c0f09b9b868ab53fdb
7
- data.tar.gz: dae5f32b172de1dff47a1d0a9c397039c7cec56d5842f7a97fa1af95c5188ea1fe8456c8c096e2e90c9ac5fc2f3f1f95628207b4344490f5f642a107e028a9e8
6
+ metadata.gz: af150a59bfa9de34841468175840cd0edfa130c38232dcd934fa04a6321ccc28550d45ca0c680323e3a55b3cc4b062bf8d22d15c8fa703caeaa77861ca2d1fdf
7
+ data.tar.gz: 6d83a87905bf1941d0108d245f26e9a17c1a9d9c2fa512ed12b4e45fb0862ebef1c389201d71584c3e5927718331c50974d0d047fdbb0af6a4db389d14e0286a
data/README.md CHANGED
@@ -1,14 +1,15 @@
1
1
  # Season
2
2
  [![Gem Version](https://badge.fury.io/rb/season.svg)](http://badge.fury.io/rb/season) [![Code Climate](https://codeclimate.com/github/joaodiogocosta/season/badges/gpa.svg)](https://codeclimate.com/github/joaodiogocosta/season) [![Build Status](https://travis-ci.org/joaodiogocosta/season.svg?branch=master)](https://travis-ci.org/joaodiogocosta/season)
3
3
 
4
- Season let's you easily query your Models by a specific date/time.
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.1'
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 assumes your models have timestamps columns (created_at and updated_at) and uses these to do its magic.
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::Scopes
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
- # And then use it as:
41
- # (Time/DateTime/String instances are allowed as arguments)
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.created_before(Time.now)
44
- User.created_after(DateTime.now)
45
- User.created_between(Time.now - 1.week, '31-01-2015')
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.updated_before(DateTime.now)
48
- User.updated_after('01-01-2015')
49
- User.updated_between(Time.now - 1.week, Time.now)
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
- - Support user-defined date/time columns (through configuration)
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/active_record/scopes" if defined? ActiveRecord
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
+
@@ -23,7 +23,8 @@ module Season
23
23
 
24
24
  def self.auto_include_scopes
25
25
  if configuration.include_by_default
26
- ActiveRecord::Base.send(:include, Season::Scopes) if defined? ActiveRecord
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
@@ -1,6 +1,5 @@
1
1
  module Season
2
- module Scopes
3
-
2
+ module Legacy
4
3
  def self.included(base)
5
4
  base.class_eval do
6
5
  def self.created_before(date)
@@ -29,4 +28,4 @@ module Season
29
28
  end
30
29
  end
31
30
  end
32
- end
31
+ 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
@@ -1,3 +1,3 @@
1
1
  module Season
2
- VERSION = "0.1"
2
+ VERSION = "0.2"
3
3
  end
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 lets you query your ActiveRecord models by a specified period of time in an easier way.}
12
- spec.description = %q{Season lets you query your ActiveRecord models by a specified period of time in an easier way.}
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
 
@@ -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.1'
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-07 00:00:00.000000000 Z
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 lets you query your ActiveRecord models by a specified period
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/active_record/scopes_spec.rb
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 lets you query your ActiveRecord models by a specified period of time
158
- in an easier way.
158
+ summary: Season automatically creates scopes for your models' datetime columns.
159
159
  test_files:
160
- - spec/active_record/scopes_spec.rb
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