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 CHANGED
@@ -3,6 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
+ .idea/
6
7
  Gemfile.lock
7
8
  InstalledFiles
8
9
  _yardoc
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
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 by date-pickers or text-input fields need to be
4
- converted from their string format to a ruby Date to be able to be saved
5
- and manipulated. This gem provides a simple controller add-on to
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
- Include the controller additions in the controller that needs to parse
25
- date parameters and then specify dates to be formatted:
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
- Or specify a namespace for each parameter individually:
49
+ Date format can be passed as an option (default is `%m/%d/%Y`):
50
50
  ```ruby
51
- include DateParams::ControllerAdditions
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
- Date format can be passed as an option (default is `%m/%d/%Y`):
54
+ ### datetime_params
55
+
56
+ Specify the datetime fields that need to be parsed:
56
57
  ```ruby
57
- include DateParams::ControllerAdditions
58
- date_params :search_on, :sign_up_on, date_format: '%d-%m-%Y'
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
- # Usage:
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
- controller.parse_date_params(args, options)
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
- if param_path.length > 1
44
- param_key = param_path.pop
45
- param_path.each { |k| traversed_params = traversed_params.try :[], k }
46
- else
47
- param_key = param_path.first
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
- def parse_date_params(the_params, options)
58
- the_params.each{ |param| parse_date_param! param, options }
59
- end
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
@@ -1,3 +1,3 @@
1
1
  module DateParams
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/date_params.rb CHANGED
@@ -1,4 +1,6 @@
1
+ require 'date_params/controller_additions'
2
+
1
3
  module DateParams
2
4
  autoload :VERSION, 'date_params/version'
3
- autoload :ControllerAdditions, 'date_params/controller_additions.rb'
5
+ autoload :Parser, 'date_params/parser'
4
6
  end
@@ -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
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
+ require 'pry-debugger'
3
4
 
4
5
  require 'date_params'
5
6
 
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: 1.0.0
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-04-23 00:00:00.000000000 Z
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/date_picker/controller_additions_spec.rb
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/date_picker/controller_additions_spec.rb
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