date_params 1.0.0 → 2.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.
- data/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/HISTORY.md +10 -0
- data/README.md +29 -14
- data/date_params.gemspec +2 -0
- data/lib/date_params/controller_additions.rb +14 -43
- data/lib/date_params/parser.rb +60 -0
- data/lib/date_params/version.rb +1 -1
- data/lib/date_params.rb +3 -1
- data/spec/date_params/parser_spec.rb +99 -0
- data/spec/spec_helper.rb +1 -0
- metadata +40 -4
- data/spec/date_picker/controller_additions_spec.rb +0 -58
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/HISTORY.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# 2.0.0 / 2013-05-03
|
2
|
+
|
3
|
+
* Removed support for specifying the namespace as an array in preference of the the `:namespace` option.
|
4
|
+
* Added `datetime_parser` controller method for parsing date and time input fields to a DateTimeobject.
|
5
|
+
* Added travis support
|
6
|
+
* Removed the need to include DateParams::ControllerAdditions into the controller
|
7
|
+
|
8
|
+
# 1.0.0 / 2013-04-23
|
9
|
+
|
10
|
+
* Initial release
|
data/README.md
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# DateParams
|
2
2
|
|
3
|
-
Dates passed in
|
4
|
-
converted from their string format to a ruby Date to be able to be saved
|
5
|
-
and manipulated. This gem provides
|
3
|
+
Dates and times passed in as strings date-pickers or time-pickers need to be
|
4
|
+
converted from their string format to a ruby Date or DateTime to be able to be saved
|
5
|
+
and manipulated. This gem provides two simple controller add-ons to
|
6
6
|
facilitate the conversion.
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
10
|
+
Rails 3.x and Ruby 1.9.3 or 2.x required.
|
11
|
+
|
10
12
|
Add this line to your application's Gemfile:
|
11
13
|
|
12
14
|
gem 'date_params'
|
@@ -21,12 +23,12 @@ Or install it yourself as:
|
|
21
23
|
|
22
24
|
## Usage
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
+
### date_params
|
27
|
+
|
28
|
+
Specify the dates to be parsed:
|
26
29
|
```ruby
|
27
30
|
class UsersController < ApplicationController
|
28
31
|
# e.g. parameters come in as: { sign_up_on: '01/05/2013' }
|
29
|
-
include DateParams::ControllerAdditions
|
30
32
|
date_params :sign_up_on
|
31
33
|
# and now params[:sign_up_on] is a Date object
|
32
34
|
end
|
@@ -34,7 +36,6 @@ end
|
|
34
36
|
|
35
37
|
Any options that a `before_filter` accepts can be passed in:
|
36
38
|
```ruby
|
37
|
-
include DateParams::ControllerAdditions
|
38
39
|
date_params :sign_up_on, only: [:index]
|
39
40
|
```
|
40
41
|
|
@@ -42,20 +43,34 @@ If date fields are namespaced in a model that can be specified with the
|
|
42
43
|
`namespace` option:
|
43
44
|
```ruby
|
44
45
|
# will parse parameters in the format of: { user: { searched_on: '01/04/2013', sign_up_on: '04/03/2013' } }
|
45
|
-
include DateParams::ControllerAdditions
|
46
46
|
date_params :searched_on, :sign_up_on, namespace: :user
|
47
47
|
```
|
48
48
|
|
49
|
-
|
49
|
+
Date format can be passed as an option (default is `%m/%d/%Y`):
|
50
50
|
```ruby
|
51
|
-
|
52
|
-
date_params [:user, :searched_on], [:company, :sign_up_on]
|
51
|
+
date_params :search_on, :sign_up_on, date_format: '%d-%m-%Y'
|
53
52
|
```
|
54
53
|
|
55
|
-
|
54
|
+
### datetime_params
|
55
|
+
|
56
|
+
Specify the datetime fields that need to be parsed:
|
56
57
|
```ruby
|
57
|
-
|
58
|
-
|
58
|
+
class UsersController < ApplicationController
|
59
|
+
# e.g. parameters come in as: { sign_up_at_date: '01/05/2013', sign_up_at_time: '7:30 pm' }
|
60
|
+
datetime_params :sign_up_at
|
61
|
+
# and now params[:sign_up_at] is a timezone-aware DateTime object
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
In addition to the `:namespace` and `:date_format` options, the time format can be specified
|
66
|
+
(default is `%I:%M %p`):
|
67
|
+
```ruby
|
68
|
+
date_params :sign_up_at, time_format: '%H:%M:%S'
|
69
|
+
```
|
70
|
+
|
71
|
+
To specify exactly which fields should be parsed:
|
72
|
+
```ruby
|
73
|
+
date_params { date: :sign_up_on, time: :sign_up_time, field: :sign_up_at }, only: :create
|
59
74
|
```
|
60
75
|
|
61
76
|
## Contributing
|
data/date_params.gemspec
CHANGED
@@ -19,8 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_dependency 'activesupport'
|
22
|
+
spec.add_dependency 'tzinfo'
|
22
23
|
|
23
24
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
24
25
|
spec.add_development_dependency 'rake'
|
25
26
|
spec.add_development_dependency 'rspec'
|
27
|
+
spec.add_development_dependency 'pry-debugger'
|
26
28
|
end
|
@@ -1,61 +1,32 @@
|
|
1
|
-
require 'date'
|
2
1
|
require 'active_support/concern'
|
3
|
-
require 'active_support/core_ext/object/try'
|
4
|
-
require 'active_support/core_ext/object/blank'
|
5
2
|
|
6
3
|
module DateParams
|
7
4
|
module ControllerAdditions
|
8
5
|
extend ActiveSupport::Concern
|
9
6
|
|
10
7
|
module ClassMethods
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# To convert only on specific actions use:
|
14
|
-
# date_params :param_name, [:namespaced, :param_name], only: :action_name
|
15
|
-
# If all variables are in a common namespace, use the namespace option:
|
16
|
-
# date_params :param_name1, :param_name2, namespace: :namespaced
|
17
|
-
# @see #parse_date_param!
|
8
|
+
# Converts a text field with a date, in a specified format, into a Date object
|
18
9
|
def date_params(*args)
|
19
10
|
options = args.extract_options!
|
20
11
|
before_filter options do |controller|
|
21
|
-
|
12
|
+
args.each { |param| DateParams::Parser.new(param, options, controller.params).parse_date_param! }
|
22
13
|
end
|
23
14
|
end
|
24
|
-
end
|
25
|
-
|
26
|
-
# Usage:
|
27
|
-
#
|
28
|
-
# To convert params[:my_date]
|
29
|
-
# date_params :my_date
|
30
|
-
#
|
31
|
-
# To convert params[:my_model][:my_date1] use one of the following:
|
32
|
-
# parse_date_param!([:my_model, :my_date1])
|
33
|
-
# parse_date_param!(:my_date1, namespace: :my_model)
|
34
|
-
#
|
35
|
-
# if the format of the data is not '%m/%d/%Y'
|
36
|
-
# parse_date_param!(:my_date1, date_format: '%m/%Y')
|
37
|
-
def parse_date_param!(param, options)
|
38
|
-
param_path = Array(param).dup
|
39
|
-
param_path.unshift options[:namespace] if options[:namespace] && param_path.length == 1
|
40
|
-
date_format = options.fetch(:date_format, '%m/%d/%Y')
|
41
|
-
traversed_params = params
|
42
15
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
16
|
+
# Similar to #date_params, but parses a date input field and a time input field
|
17
|
+
# and combines them into a new timezone-aware datetime field.
|
18
|
+
def datetime_params(*args)
|
19
|
+
options = args.extract_options!
|
20
|
+
before_filter options do |controller|
|
21
|
+
args.each { |param| DateParams::Parser.new(param, options, controller.params).parse_datetime_param! }
|
22
|
+
end
|
48
23
|
end
|
49
|
-
|
50
|
-
value = traversed_params.try(:[], param_key)
|
51
|
-
return nil if value.blank?
|
52
|
-
date_format = value =~ /\d{4}-\d{2}-\d{2}/ ? '%Y-%m-%d' : date_format
|
53
|
-
date = Date.strptime(value, date_format)
|
54
|
-
traversed_params[param_key] = date if date
|
55
24
|
end
|
25
|
+
end
|
26
|
+
end
|
56
27
|
|
57
|
-
|
58
|
-
|
59
|
-
|
28
|
+
if defined? ActionController::Base
|
29
|
+
ActionController::Base.class_eval do
|
30
|
+
include DateParams::ControllerAdditions
|
60
31
|
end
|
61
32
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'time'
|
2
|
+
require 'date'
|
3
|
+
require 'tzinfo'
|
4
|
+
require 'active_support/core_ext/time/zones'
|
5
|
+
require 'active_support/core_ext/time/calculations'
|
6
|
+
require 'active_support/time_with_zone'
|
7
|
+
require 'active_support/core_ext/object/try'
|
8
|
+
require 'active_support/core_ext/object/blank'
|
9
|
+
require 'active_support/core_ext/hash/keys'
|
10
|
+
|
11
|
+
class DateParams::Parser
|
12
|
+
attr_reader :param, :options, :params, :date_format, :time_format
|
13
|
+
def initialize(param, options, params)
|
14
|
+
@param = param
|
15
|
+
@options = options
|
16
|
+
@params = params
|
17
|
+
@date_format = options.fetch :date_format, '%m/%d/%Y'
|
18
|
+
@time_format = options.fetch :time_format, '%I:%M %p'
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse_date_param!(field = param)
|
22
|
+
date_string = traversed_params.try(:[], field)
|
23
|
+
return if date_string.blank?
|
24
|
+
inferred_date_format = date_string =~ /\d{4}-\d{2}-\d{2}/ ? '%Y-%m-%d' : date_format
|
25
|
+
date = Date.strptime(date_string, inferred_date_format)
|
26
|
+
traversed_params[field] = date if date
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_datetime_param!
|
30
|
+
if param.is_a? Hash
|
31
|
+
fields = param
|
32
|
+
fields.assert_valid_keys :date, :time, :field
|
33
|
+
else
|
34
|
+
fields = {
|
35
|
+
date: "#{param}_date".to_sym,
|
36
|
+
time: "#{param}_time".to_sym,
|
37
|
+
field: param
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
date = parse_date_param! fields[:date]
|
42
|
+
return if date.blank?
|
43
|
+
time_string = traversed_params.try(:[], fields[:time])
|
44
|
+
return if time_string.blank?
|
45
|
+
datetime_format = "%Y-%m-%dT#{time_format}%z"
|
46
|
+
datetime_string = "#{date.iso8601}T#{time_string}#{Time.zone.name}"
|
47
|
+
datetime = Time.strptime(datetime_string, datetime_format).in_time_zone(Time.zone)
|
48
|
+
traversed_params[fields[:field]] = datetime if datetime
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def traversed_params
|
54
|
+
traversed_params = params
|
55
|
+
if options[:namespace].present?
|
56
|
+
traversed_params = traversed_params.try :[], options[:namespace]
|
57
|
+
end
|
58
|
+
traversed_params
|
59
|
+
end
|
60
|
+
end
|
data/lib/date_params/version.rb
CHANGED
data/lib/date_params.rb
CHANGED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DateParams::Parser do
|
4
|
+
let(:options) { {} }
|
5
|
+
let(:parser) { described_class.new param, options, params }
|
6
|
+
|
7
|
+
describe '#parse_date_param!' do
|
8
|
+
let(:params) do
|
9
|
+
{
|
10
|
+
date: '08/10/2012',
|
11
|
+
paginated_date: '2012-08-10',
|
12
|
+
invalid_date: '000000',
|
13
|
+
user: {
|
14
|
+
notified_on: '08/10/2012'
|
15
|
+
}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
let(:date) { Date.parse '2012-08-10' }
|
19
|
+
|
20
|
+
context 'invalid format' do
|
21
|
+
let(:param) { :invalid_date }
|
22
|
+
it 'should raise when unknown format' do
|
23
|
+
expect { expect parser.parse_date_param! }.to raise_error ArgumentError
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'valid format' do
|
28
|
+
before { parser.parse_date_param! }
|
29
|
+
|
30
|
+
describe 'param field is updated' do
|
31
|
+
let(:param) { :date }
|
32
|
+
subject { params[:date] }
|
33
|
+
it { should eq date }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'namespace option is present' do
|
37
|
+
let(:param) { :notified_on }
|
38
|
+
let(:options) { { namespace: :user } }
|
39
|
+
subject { params[:user][:notified_on] }
|
40
|
+
it { should eq date }
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'date format is yyyy-mm-dd from pagination' do
|
44
|
+
let(:param) { :paginated_date }
|
45
|
+
subject { params[:paginated_date] }
|
46
|
+
it { should eq date }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#parse_datetime_param!' do
|
52
|
+
before { Time.zone = 'EST' }
|
53
|
+
let(:params) do
|
54
|
+
{
|
55
|
+
created_at_date: '08/10/2012',
|
56
|
+
created_at_time: '12:30 am',
|
57
|
+
invalid_time: '1111',
|
58
|
+
empty_time: '',
|
59
|
+
user: {
|
60
|
+
notified_at_date: '08/10/2012',
|
61
|
+
notified_at_time: '12:30 am'
|
62
|
+
}
|
63
|
+
}
|
64
|
+
end
|
65
|
+
let(:datetime) { Time.zone.parse '2012-08-10 00:30' }
|
66
|
+
|
67
|
+
context 'invalid format' do
|
68
|
+
let(:param) { { date: :created_at_date, time: :invalid_time, field: :created_at } }
|
69
|
+
it 'should raise when unknown format' do
|
70
|
+
expect { expect parser.parse_datetime_param! }.to raise_error ArgumentError
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'valid format' do
|
75
|
+
before { parser.parse_datetime_param! }
|
76
|
+
|
77
|
+
describe 'param field is updated' do
|
78
|
+
let(:param) { :created_at }
|
79
|
+
subject { params[:created_at] }
|
80
|
+
it { should eq datetime }
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'namespace option is present' do
|
84
|
+
let(:param) { :notified_at }
|
85
|
+
let(:options) { { namespace: :user } }
|
86
|
+
subject { params[:user][:notified_at] }
|
87
|
+
it { should eq datetime }
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'time is empty' do
|
91
|
+
let(:param) { { date: :created_at_date, time: :empty_time, field: :created_at } }
|
92
|
+
it 'parses the date but not the time' do
|
93
|
+
params[:created_at_date].should eq datetime.to_date
|
94
|
+
params[:created_at].should be_nil
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: date_params
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-05-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: tzinfo
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: bundler
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,6 +91,22 @@ dependencies:
|
|
75
91
|
- - ! '>='
|
76
92
|
- !ruby/object:Gem::Version
|
77
93
|
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: pry-debugger
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
78
110
|
description: Dates passed in by date-pickers or text-input fields to a rails controller
|
79
111
|
need to be converted to a ruby Date to be able to be saved and manipulated. This
|
80
112
|
gem provides a simple controller add-on to facilitate the conversion.
|
@@ -85,15 +117,18 @@ extensions: []
|
|
85
117
|
extra_rdoc_files: []
|
86
118
|
files:
|
87
119
|
- .gitignore
|
120
|
+
- .travis.yml
|
88
121
|
- Gemfile
|
122
|
+
- HISTORY.md
|
89
123
|
- LICENSE.txt
|
90
124
|
- README.md
|
91
125
|
- Rakefile
|
92
126
|
- date_params.gemspec
|
93
127
|
- lib/date_params.rb
|
94
128
|
- lib/date_params/controller_additions.rb
|
129
|
+
- lib/date_params/parser.rb
|
95
130
|
- lib/date_params/version.rb
|
96
|
-
- spec/
|
131
|
+
- spec/date_params/parser_spec.rb
|
97
132
|
- spec/spec_helper.rb
|
98
133
|
homepage: https://github.com/LessonPlanet/date_params
|
99
134
|
licenses:
|
@@ -121,5 +156,6 @@ signing_key:
|
|
121
156
|
specification_version: 3
|
122
157
|
summary: Convert date string parameters in a rails controller into Date objects.
|
123
158
|
test_files:
|
124
|
-
- spec/
|
159
|
+
- spec/date_params/parser_spec.rb
|
125
160
|
- spec/spec_helper.rb
|
161
|
+
has_rdoc:
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe DateParams::ControllerAdditions do
|
4
|
-
let(:mock_controller) do
|
5
|
-
Class.new do
|
6
|
-
attr_accessor :params
|
7
|
-
include DateParams::ControllerAdditions
|
8
|
-
end.new
|
9
|
-
end
|
10
|
-
let(:custom_params) do
|
11
|
-
{
|
12
|
-
date: '08/10/2012',
|
13
|
-
paginated_date: '2012-08-10',
|
14
|
-
invalid_date: '000000',
|
15
|
-
model: {
|
16
|
-
date: '08/10/2012'
|
17
|
-
}
|
18
|
-
}
|
19
|
-
end
|
20
|
-
let(:date) { Date.parse '2012-08-10' }
|
21
|
-
|
22
|
-
context 'invalid format' do
|
23
|
-
let(:param_spec) { :invalid_date }
|
24
|
-
it 'should raise when unknown format' do
|
25
|
-
mock_controller.params = custom_params
|
26
|
-
expect { mock_controller.parse_date_param!(param_spec, {}) }.to raise_error ArgumentError, 'invalid date'
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'valid format' do
|
31
|
-
before do
|
32
|
-
mock_controller.params = custom_params
|
33
|
-
mock_controller.parse_date_param!(param_spec, {})
|
34
|
-
end
|
35
|
-
|
36
|
-
context 'should update params' do
|
37
|
-
let(:param_spec) { :date }
|
38
|
-
subject { mock_controller.params[:date] }
|
39
|
-
it { should eq date }
|
40
|
-
end
|
41
|
-
|
42
|
-
context 'should update nested params' do
|
43
|
-
let(:param_spec) { [:model, :date] }
|
44
|
-
subject { mock_controller.params[:model][:date] }
|
45
|
-
it { should eq date }
|
46
|
-
|
47
|
-
it 'should not change the original' do
|
48
|
-
param_spec.should == [:model, :date]
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'when date format is yyyy-mm-dd from pagination' do
|
53
|
-
let(:param_spec) { :paginated_date }
|
54
|
-
subject { mock_controller.params[:paginated_date] }
|
55
|
-
it { should eq date }
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|