action_args 1.0.4 → 1.1.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 +7 -0
- data/Gemfile +1 -1
- data/README.md +26 -1
- data/Rakefile +1 -1
- data/gemfiles/rails_32.gemfile +1 -1
- data/gemfiles/rails_40.gemfile +1 -1
- data/lib/action_args.rb +1 -0
- data/lib/action_args/abstract_controller.rb +4 -11
- data/lib/action_args/params_handler.rb +38 -0
- data/lib/action_args/version.rb +1 -1
- data/spec/controllers/action_args_controller_spec.rb +7 -0
- data/spec/controllers/kwargs_controller_spec.rb +26 -0
- data/spec/controllers/strong_parameters_spec.rb +12 -0
- data/spec/fake_app.rb +20 -3
- data/spec/kwargs_controllers.rb +8 -0
- data/spec/params_handler/params_handler_spec.rb +158 -0
- metadata +14 -9
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e820e5d9674aa0054496752320674fc8c57c364d
|
4
|
+
data.tar.gz: c854a76604f95d555872c93cc360ad42d19425e8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b82fea159869a228853c9362d9b321c9a4ef3e9f88b20be10a74b16c96c494317a96fa99936ff7ae2261812645cf89c6e68f959ee802eb942310c35df6126ccf
|
7
|
+
data.tar.gz: 85e3e9513651c34edce33142cc2fa4dc0d539f1eb9163a0464bcdb82686ebac6e549b2963406b56605f3376519b1d3847b576d2f14949749704ef80d4351960e
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -158,7 +158,7 @@ You may notice that
|
|
158
158
|
|
159
159
|
## Supported versions
|
160
160
|
|
161
|
-
* Ruby 1.9.2, 1.9.3, 2.0.0 (trunk), JRuby & Rubinius with 1.9 mode
|
161
|
+
* Ruby 1.9.2, 1.9.3, 2.0.0, 2.1.0 (trunk), JRuby & Rubinius with 1.9 mode
|
162
162
|
|
163
163
|
* Rails 3.0.x, 3.1.x, 3.2.x, 4.0 (edge)
|
164
164
|
|
@@ -201,6 +201,31 @@ class BooksController < ApplicationController
|
|
201
201
|
end
|
202
202
|
```
|
203
203
|
|
204
|
+
### Default parameter values
|
205
|
+
|
206
|
+
You are of course able to specify default values for action parameters such as:
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
class BooksController < ApplicationController
|
210
|
+
def index(author_id = nil, page = 1)
|
211
|
+
...
|
212
|
+
end
|
213
|
+
end
|
214
|
+
```
|
215
|
+
|
216
|
+
However, due to some implementational reasons, the `page` variable will be actually defaulted to nil when `page` parameter was not given.
|
217
|
+
|
218
|
+
In order to provide default parameter values in perfect Ruby manner, we recommend you to use the Ruby 2.0 "keyword arguments" syntax instead.
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
class BooksController < ApplicationController
|
222
|
+
def index(author_id: nil, page: 1)
|
223
|
+
...
|
224
|
+
end
|
225
|
+
end
|
226
|
+
```
|
227
|
+
|
228
|
+
This way, the `page` parameter will be defaulted to 1 as everyone might expect.
|
204
229
|
|
205
230
|
## Copyright
|
206
231
|
|
data/Rakefile
CHANGED
data/gemfiles/rails_32.gemfile
CHANGED
data/gemfiles/rails_40.gemfile
CHANGED
data/lib/action_args.rb
CHANGED
@@ -4,16 +4,9 @@ module AbstractController
|
|
4
4
|
def send_action(method_name, *args)
|
5
5
|
return send method_name, *args unless args.empty?
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
values =
|
10
|
-
params.require key if type == :req
|
11
|
-
if (key == target_model_name) && permitted_attributes
|
12
|
-
params[key].try :permit, *permitted_attributes
|
13
|
-
else
|
14
|
-
params[key]
|
15
|
-
end
|
16
|
-
end
|
7
|
+
method_parameters = method(method_name).parameters
|
8
|
+
ActionArgs::ParamsHandler.strengthen_params!(self.class, method_parameters, params)
|
9
|
+
values = ActionArgs::ParamsHandler.extract_method_arguments_from_params method_parameters, params
|
17
10
|
send method_name, *values
|
18
11
|
end
|
19
12
|
|
@@ -37,7 +30,7 @@ module AbstractController
|
|
37
30
|
def send_action(method_name, *args)
|
38
31
|
return send method_name, *args unless args.empty?
|
39
32
|
|
40
|
-
values = method(method_name).parameters
|
33
|
+
values = ActionArgs::ParamsHandler.extract_method_arguments_from_params method(method_name).parameters, params
|
41
34
|
send method_name, *values
|
42
35
|
end
|
43
36
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module ActionArgs
|
2
|
+
module ParamsHandler
|
3
|
+
# converts the request params Hash into an Array to be passed into the target Method
|
4
|
+
def self.extract_method_arguments_from_params(method_parameters, params)
|
5
|
+
kwargs = {}
|
6
|
+
parameter_names = method_parameters.map(&:last)
|
7
|
+
method_parameters.reverse_each do |type, key|
|
8
|
+
case type
|
9
|
+
when :req
|
10
|
+
next
|
11
|
+
when :key
|
12
|
+
kwargs[key] = params[key] if params.has_key? key
|
13
|
+
when :opt
|
14
|
+
break if params.has_key? key
|
15
|
+
end
|
16
|
+
# omitting parameters that are :block, :rest, :opt without a param, and :key without a param
|
17
|
+
parameter_names.delete key
|
18
|
+
end
|
19
|
+
|
20
|
+
values = parameter_names.map {|k| params[k]}
|
21
|
+
values << kwargs if kwargs.any?
|
22
|
+
values
|
23
|
+
end
|
24
|
+
|
25
|
+
# permits declared model attributes in the params Hash
|
26
|
+
# note that this method mutates the given params Hash
|
27
|
+
def self.strengthen_params!(controller_class, method_parameters, params)
|
28
|
+
target_model_name = controller_class.name.sub(/.+::/, '').sub(/Controller$/, '').singularize.underscore.to_sym
|
29
|
+
permitted_attributes = controller_class.instance_variable_get '@permitted_attributes'
|
30
|
+
|
31
|
+
method_parameters.each do |type, key|
|
32
|
+
if (key == target_model_name) && permitted_attributes
|
33
|
+
params[key] = params.require(key).try :permit, *permitted_attributes
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/action_args/version.rb
CHANGED
@@ -2,14 +2,21 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe BooksController do
|
4
4
|
describe 'GET index (having an optional parameter)' do
|
5
|
+
before do
|
6
|
+
@books = []
|
7
|
+
Book.delete_all
|
8
|
+
100.times {|i| @books << Book.create!(title: 'book'+i.to_s) }
|
9
|
+
end
|
5
10
|
context 'without page parameter' do
|
6
11
|
before { get :index }
|
7
12
|
its(:response) { should be_success }
|
13
|
+
it { expect(assigns(:books)).to match_array(@books[0..9]) }
|
8
14
|
end
|
9
15
|
|
10
16
|
context 'with page parameter' do
|
11
17
|
before { get :index, page: 3 }
|
12
18
|
its(:response) { should be_success }
|
19
|
+
it { expect(assigns(:books)).to match_array(@books[20..29]) }
|
13
20
|
end
|
14
21
|
|
15
22
|
context 'first param is nil and second is not nil' do
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe KwBooksController do
|
4
|
+
describe 'GET index (having an optional parameter)' do
|
5
|
+
context 'without giving any kw parameter' do
|
6
|
+
before { get :index, author_name: 'nari' }
|
7
|
+
its(:response) { should be_success }
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'with kw parameter defaults to non-nil value' do
|
11
|
+
before { get :index, author_name: 'nari', page: 3 }
|
12
|
+
subject { eval response.body }
|
13
|
+
its([:author_name]) { should == 'nari' }
|
14
|
+
its([:page]) { should == '3' }
|
15
|
+
its([:q]) { should == nil }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with kw parameter defaults to nil' do
|
19
|
+
before { get :index, author_name: 'nari', q: 'Rails' }
|
20
|
+
subject { eval response.body }
|
21
|
+
its([:author_name]) { should == 'nari' }
|
22
|
+
its([:page]) { should == '1' }
|
23
|
+
its([:q]) { should == 'Rails' }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end if RUBY_VERSION >= '2'
|
@@ -13,4 +13,16 @@ if Rails::VERSION::MAJOR >= 4
|
|
13
13
|
it { expect { post :create, :store => {name: 'Tatsu-zine', url: 'http://tatsu-zine.com'} }.to change(Store, :count).by(1) }
|
14
14
|
end
|
15
15
|
end
|
16
|
+
|
17
|
+
describe Admin::BooksController do
|
18
|
+
context "this controller doesn't permit price of new book" do
|
19
|
+
describe 'POST create' do
|
20
|
+
before { post :create, :book => {title: 'naruhoUnix', price: 30} }
|
21
|
+
|
22
|
+
it 'should not save price of the book' do
|
23
|
+
expect(Book.last.price).to be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
16
28
|
end
|
data/spec/fake_app.rb
CHANGED
@@ -15,7 +15,12 @@ ActionArgsTestApp::Application.initialize!
|
|
15
15
|
ActionArgsTestApp::Application.routes.draw do
|
16
16
|
resources :authors
|
17
17
|
resources :books
|
18
|
+
resources :kw_books # 2.0+ only
|
18
19
|
resources :stores
|
20
|
+
|
21
|
+
namespace :admin do
|
22
|
+
resources :books
|
23
|
+
end
|
19
24
|
end
|
20
25
|
|
21
26
|
# models
|
@@ -40,10 +45,10 @@ class AuthorsController < ApplicationController
|
|
40
45
|
end
|
41
46
|
class BooksController < ApplicationController
|
42
47
|
# optional parameter
|
43
|
-
def index(page = 1, q = nil)
|
44
|
-
@books = Book.limit(
|
48
|
+
def index(page = 1, q = nil, limit = 10)
|
49
|
+
@books = Book.limit(limit.to_i).offset(([page.to_i - 1, 0].max) * 10)
|
45
50
|
@books = @books.where('title like ?', "%#{q}%") unless q.blank?
|
46
|
-
render text: 'index'
|
51
|
+
render text: 'index', books: @books
|
47
52
|
end
|
48
53
|
|
49
54
|
def show(id)
|
@@ -71,8 +76,20 @@ if Rails::VERSION::MAJOR >= 4
|
|
71
76
|
render text: @store.name
|
72
77
|
end
|
73
78
|
end
|
79
|
+
module Admin
|
80
|
+
class BooksController < ::ApplicationController
|
81
|
+
permits :title
|
82
|
+
|
83
|
+
def create(book)
|
84
|
+
@book = Book.create! book
|
85
|
+
render text: @book.title
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
74
89
|
end
|
75
90
|
|
91
|
+
require_relative 'kwargs_controllers' if RUBY_VERSION >= '2'
|
92
|
+
|
76
93
|
# migrations
|
77
94
|
class CreateAllTables < ActiveRecord::Migration
|
78
95
|
def self.up
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActionArgs::ParamsHandler do
|
4
|
+
# ActionArgs::ParamsHandler.extract_method_arguments_from_params(method_parameters, params)
|
5
|
+
describe 'extract_method_arguments_from_params' do
|
6
|
+
let(:params) { {a: '1', b: '2'} }
|
7
|
+
subject { ActionArgs::ParamsHandler.extract_method_arguments_from_params method(:m).parameters, params }
|
8
|
+
context 'no parameters' do
|
9
|
+
before do
|
10
|
+
def m() end
|
11
|
+
end
|
12
|
+
it { should == [] }
|
13
|
+
end
|
14
|
+
|
15
|
+
context '1 req' do
|
16
|
+
before do
|
17
|
+
def m(a) end
|
18
|
+
end
|
19
|
+
it { should == ['1'] }
|
20
|
+
end
|
21
|
+
|
22
|
+
context '2 reqs' do
|
23
|
+
before do
|
24
|
+
def m(a, b) end
|
25
|
+
end
|
26
|
+
it { should == ['1', '2'] }
|
27
|
+
end
|
28
|
+
|
29
|
+
context '1 opt with value' do
|
30
|
+
before do
|
31
|
+
def m(a = 'a') end
|
32
|
+
end
|
33
|
+
it { should == ['1'] }
|
34
|
+
end
|
35
|
+
|
36
|
+
context '1 opt without value' do
|
37
|
+
before do
|
38
|
+
def m(x = 'x') end
|
39
|
+
end
|
40
|
+
it { should == [] }
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'req, opt with value' do
|
44
|
+
before do
|
45
|
+
def m(a, b = 'b') end
|
46
|
+
end
|
47
|
+
it { should == ['1', '2'] }
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'req, opt without value' do
|
51
|
+
before do
|
52
|
+
def m(a, x = 'x') end
|
53
|
+
end
|
54
|
+
it { should == ['1'] }
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'opt with value, opt with value' do
|
58
|
+
before do
|
59
|
+
def m(a = 'a', b = 'b') end
|
60
|
+
end
|
61
|
+
it { should == ['1', '2'] }
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'opt with value, opt without value' do
|
65
|
+
before do
|
66
|
+
def m(a = 'a', x = 'x') end
|
67
|
+
end
|
68
|
+
it { should == ['1'] }
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'opt without value, opt with value' do
|
72
|
+
before do
|
73
|
+
def m(x = 'x', a = 'a') end
|
74
|
+
end
|
75
|
+
it { should == [nil, '1'] }
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'opt without value, opt without value' do
|
79
|
+
before do
|
80
|
+
def m(x = 'x', y = 'y') end
|
81
|
+
end
|
82
|
+
it { should == [] }
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'opt with value, req' do
|
86
|
+
before do
|
87
|
+
def m(a = 'a', b) end
|
88
|
+
end
|
89
|
+
it { should == ['1', '2'] }
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'opt without value, req' do
|
93
|
+
before do
|
94
|
+
def m(x = 'x', a) end
|
95
|
+
end
|
96
|
+
it { should == ['1'] }
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'opt without value, opt with value, req' do
|
100
|
+
before do
|
101
|
+
def m(x = 'x', b = 'b', a) end
|
102
|
+
end
|
103
|
+
it { should == [nil, '2', '1'] }
|
104
|
+
end
|
105
|
+
context 'opt with value, opt without value, req' do
|
106
|
+
before do
|
107
|
+
def m(b = 'b', x = 'x', a) end
|
108
|
+
end
|
109
|
+
it { should == ['2', '1'] }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
if defined? ActionController::StrongParameters
|
114
|
+
# strengthen_params!(controller_class, method_parameters, params)
|
115
|
+
describe 'strengthen_params!' do
|
116
|
+
before { ActionArgs::ParamsHandler.strengthen_params! controller, controller.new.method(:a).parameters, params }
|
117
|
+
let(:params) { ActionController::Parameters.new(x: '1', y: '2', foo: {a: 'a', b: 'b'}, bar: {a: 'a', b: 'b'}, baz: {a: 'a', b: 'b'}, hoge: {a: 'a', b: 'b'}, fuga: {a: 'a', b: 'b'}) }
|
118
|
+
|
119
|
+
context 'requiring via :req, permitting all scalars' do
|
120
|
+
let(:controller) { FooController ||= Class.new(ApplicationController) { permits :a, :b; def a(foo) end } }
|
121
|
+
subject { params[:foo] }
|
122
|
+
it { should be_permitted }
|
123
|
+
its([:a]) { should be }
|
124
|
+
its([:b]) { should be }
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'requiring via :req, not permitting all scalars' do
|
128
|
+
let(:controller) { BarController ||= Class.new(ApplicationController) { permits :a; def a(bar, x = 'x') end } }
|
129
|
+
subject { params[:bar] }
|
130
|
+
it { should be_permitted }
|
131
|
+
its([:a]) { should be }
|
132
|
+
its([:b]) { should_not be }
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'requiring via :req, not permitting any scalars' do
|
136
|
+
let(:controller) { BazController ||= Class.new(ApplicationController) { def a(baz, aho = 'omg') end } }
|
137
|
+
subject { params[:baz] }
|
138
|
+
it { should_not be_permitted }
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'requiring via :opt, permitting all scalars' do
|
142
|
+
let(:controller) { HogeController ||= Class.new(ApplicationController) { permits :a, :b; def a(hoge = {}) end } }
|
143
|
+
subject { params[:hoge] }
|
144
|
+
it { should be_permitted }
|
145
|
+
its([:a]) { should be }
|
146
|
+
its([:b]) { should be }
|
147
|
+
end
|
148
|
+
|
149
|
+
context 'requiring via :key, permitting all scalars' do
|
150
|
+
let(:controller) { FugaController ||= Class.new(ApplicationController) { permits :a, :b; def a(fuga: {}) end } }
|
151
|
+
subject { params[:fuga] }
|
152
|
+
it { should be_permitted }
|
153
|
+
its([:a]) { should be }
|
154
|
+
its([:b]) { should be }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action_args
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Akira Matsuda
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-05-21 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
13
|
description: Rails plugin gem that supports Merbish style controller action arguments.
|
15
14
|
email:
|
@@ -29,43 +28,49 @@ files:
|
|
29
28
|
- gemfiles/rails_40.gemfile
|
30
29
|
- lib/action_args.rb
|
31
30
|
- lib/action_args/abstract_controller.rb
|
31
|
+
- lib/action_args/params_handler.rb
|
32
32
|
- lib/action_args/version.rb
|
33
33
|
- lib/generators/action_args/rspec/scaffold/scaffold_generator.rb
|
34
34
|
- lib/generators/action_args/rspec/scaffold/templates/action_args_controller_spec.rb
|
35
35
|
- lib/generators/rails/action_args_scaffold_controller_generator.rb
|
36
36
|
- lib/generators/rails/templates/controller.rb
|
37
37
|
- spec/controllers/action_args_controller_spec.rb
|
38
|
+
- spec/controllers/kwargs_controller_spec.rb
|
38
39
|
- spec/controllers/ordinal_controller_spec.rb
|
39
40
|
- spec/controllers/strong_parameters_spec.rb
|
40
41
|
- spec/fake_app.rb
|
42
|
+
- spec/kwargs_controllers.rb
|
43
|
+
- spec/params_handler/params_handler_spec.rb
|
41
44
|
- spec/spec_helper.rb
|
42
45
|
homepage: http://asakusa.rubyist.net/
|
43
46
|
licenses: []
|
47
|
+
metadata: {}
|
44
48
|
post_install_message:
|
45
49
|
rdoc_options: []
|
46
50
|
require_paths:
|
47
51
|
- lib
|
48
52
|
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
53
|
requirements:
|
51
|
-
- -
|
54
|
+
- - '>='
|
52
55
|
- !ruby/object:Gem::Version
|
53
56
|
version: '0'
|
54
57
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
-
none: false
|
56
58
|
requirements:
|
57
|
-
- -
|
59
|
+
- - '>='
|
58
60
|
- !ruby/object:Gem::Version
|
59
61
|
version: '0'
|
60
62
|
requirements: []
|
61
63
|
rubyforge_project: action_args
|
62
|
-
rubygems_version:
|
64
|
+
rubygems_version: 2.0.2
|
63
65
|
signing_key:
|
64
|
-
specification_version:
|
66
|
+
specification_version: 4
|
65
67
|
summary: Controller action arguments parameterizer for Rails 3+ & Ruby 1.9+
|
66
68
|
test_files:
|
67
69
|
- spec/controllers/action_args_controller_spec.rb
|
70
|
+
- spec/controllers/kwargs_controller_spec.rb
|
68
71
|
- spec/controllers/ordinal_controller_spec.rb
|
69
72
|
- spec/controllers/strong_parameters_spec.rb
|
70
73
|
- spec/fake_app.rb
|
74
|
+
- spec/kwargs_controllers.rb
|
75
|
+
- spec/params_handler/params_handler_spec.rb
|
71
76
|
- spec/spec_helper.rb
|