action_args 0.0.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.travis.yml +15 -0
- data/README.rdoc +35 -12
- data/Rakefile +27 -0
- data/action_args.gemspec +4 -2
- data/gemfiles/rails_32.gemfile +6 -0
- data/gemfiles/rails_40.gemfile +8 -0
- data/lib/action_args.rb +5 -1
- data/lib/action_args/abstract_controller.rb +29 -1
- data/lib/action_args/version.rb +1 -1
- data/lib/generators/rails/action_args_scaffold_controller_generator.rb +1 -0
- data/lib/generators/rails/templates/controller.rb +4 -0
- data/spec/controllers/action_args_controller_spec.rb +15 -0
- data/spec/controllers/ordinal_controller_spec.rb +11 -0
- data/spec/controllers/strong_parameters_spec.rb +16 -0
- data/spec/fake_app.rb +76 -0
- data/spec/spec_helper.rb +15 -0
- metadata +36 -7
data/.gitignore
CHANGED
data/.travis.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
script: "bundle exec rake spec"
|
2
|
+
language: ruby
|
3
|
+
rvm:
|
4
|
+
- 1.9.3
|
5
|
+
- ruby-head
|
6
|
+
- jruby-head
|
7
|
+
- rbx-19mode
|
8
|
+
matrix:
|
9
|
+
allow_failures:
|
10
|
+
- rvm: ruby-head
|
11
|
+
- rvm: jruby-head
|
12
|
+
- rvm: rbx-19mode
|
13
|
+
gemfile:
|
14
|
+
- gemfiles/rails_32.gemfile
|
15
|
+
- gemfiles/rails_40.gemfile
|
data/README.rdoc
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
= ActionArgs
|
2
2
|
|
3
|
-
Controller action arguments parameterizer for Rails 3
|
3
|
+
Controller action arguments parameterizer for Rails 3+
|
4
4
|
|
5
5
|
|
6
6
|
== What is this?
|
7
7
|
|
8
|
-
ActionArgs is a Rails
|
8
|
+
ActionArgs is a Rails plugin that extends your controller action methods to look and act like simple general Ruby methods with meaningful parameters, or in short, Merbish.
|
9
9
|
|
10
10
|
|
11
11
|
== The Controllers
|
@@ -19,12 +19,39 @@ Having the following controller code:
|
|
19
19
|
end
|
20
20
|
|
21
21
|
Hitting "/hoge/fuga?piyo=foo" will call fuga('foo') and output 'foo'.
|
22
|
-
So, you do never need to touch the ugly +params+ Hash to
|
22
|
+
So, you do never need to touch the ugly +params+ Hash in order to fetch the request parameters.
|
23
|
+
|
24
|
+
|
25
|
+
== StrongParameters
|
26
|
+
|
27
|
+
ActionArgs plays very nice with Rails 4 StrongParameters.
|
28
|
+
Hashes in the action method arguments simply responds to the `permit` method.
|
29
|
+
|
30
|
+
class UsersController < ApplicationController
|
31
|
+
def create(user)
|
32
|
+
@user = User.new(user.permit(:name, :age))
|
33
|
+
...
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Moreover, ActionArgs provides declarative `permits` method for controller classes,
|
38
|
+
so that you can DRY up your `permit` calls in the most comprehensible way.
|
39
|
+
The `permits` method assumes the model class from the controller name, and
|
40
|
+
`permit`s the action arguments containing attributes for that model.
|
41
|
+
|
42
|
+
class UsersController < ApplicationController
|
43
|
+
# white-lists User model's attributes
|
44
|
+
permits :name, :age
|
45
|
+
|
46
|
+
# the given `user` parameter would be automatically permitted by ActionArgs
|
47
|
+
def create(user)
|
48
|
+
@user = User.new(user)
|
49
|
+
end
|
50
|
+
end
|
23
51
|
|
24
52
|
|
25
53
|
== The Scaffold Generator
|
26
54
|
|
27
|
-
To tell you the truth, Rails 3 is originally designed to be able to very easily add this functionality (because Carlhuda did the work on this), so perhaps the most characteristic feature of this plugin is the generator.
|
28
55
|
ActionArgs provides a custom scaffold controller generator that overwrites the default scaffold generator.
|
29
56
|
Thus, by hitting the following command:
|
30
57
|
|
@@ -35,6 +62,8 @@ The following beautiful controller code will be generated:
|
|
35
62
|
# coding: utf-8
|
36
63
|
|
37
64
|
class UsersController < ApplicationController
|
65
|
+
permits :name, :age, :email
|
66
|
+
|
38
67
|
# GET /users
|
39
68
|
def index
|
40
69
|
@users = User.all
|
@@ -94,9 +123,9 @@ You may notice that
|
|
94
123
|
|
95
124
|
== Supported versions
|
96
125
|
|
97
|
-
* Ruby 1.9.2, 1.9.3 (trunk)
|
126
|
+
* Ruby 1.9.2, 1.9.3, 2.0.0 (trunk)
|
98
127
|
|
99
|
-
* Rails 3.0.x, 3.1 (edge)
|
128
|
+
* Rails 3.0.x, 3.1.x, 3.2.x, 4.0 (edge)
|
100
129
|
|
101
130
|
|
102
131
|
== Installation
|
@@ -135,15 +164,9 @@ Each action method parameter name corresponds to +params+ key name. For example,
|
|
135
164
|
|
136
165
|
== Todo
|
137
166
|
|
138
|
-
* specs
|
139
167
|
* other Ruby implementations
|
140
168
|
|
141
169
|
|
142
|
-
== Conclusion
|
143
|
-
|
144
|
-
Ruby 1.9 on Rails 3 FTW!
|
145
|
-
|
146
|
-
|
147
170
|
== Copyright
|
148
171
|
|
149
172
|
Copyright (c) 2011 Asakusa.rb. See MIT-LICENSE for further details.
|
data/Rakefile
CHANGED
@@ -1,2 +1,29 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
8
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
9
|
+
end
|
10
|
+
|
11
|
+
task :default => 'spec:all'
|
12
|
+
|
13
|
+
namespace :spec do
|
14
|
+
%w(rails_32 rails_40).each do |gemfile|
|
15
|
+
desc "Run Tests against #{gemfile}"
|
16
|
+
task gemfile do
|
17
|
+
sh "BUNDLE_GEMFILE='gemfiles/#{gemfile}.gemfile' bundle --quiet"
|
18
|
+
sh "BUNDLE_GEMFILE='gemfiles/#{gemfile}.gemfile' bundle exec rake -t spec"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Run Tests against all ORMs'
|
23
|
+
task :all do
|
24
|
+
%w(rails_32 rails_40).each do |gemfile|
|
25
|
+
sh "BUNDLE_GEMFILE='gemfiles/#{gemfile}.gemfile' bundle --quiet"
|
26
|
+
sh "BUNDLE_GEMFILE='gemfiles/#{gemfile}.gemfile' bundle exec rake spec"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/action_args.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ['Akira Matsuda']
|
10
10
|
s.email = ['ronnie@dio.jp']
|
11
11
|
s.homepage = 'http://asakusa.rubyist.net/'
|
12
|
-
s.summary = 'Controller action arguments parameterizer for Rails 3
|
13
|
-
s.description = 'Rails
|
12
|
+
s.summary = 'Controller action arguments parameterizer for Rails 3+ & Ruby 1.9+'
|
13
|
+
s.description = 'Rails plugin gem that supports Merbish style controller action arguments.'
|
14
14
|
|
15
15
|
s.rubyforge_project = 'action_args'
|
16
16
|
|
@@ -18,4 +18,6 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency 'sqlite3', ['>= 0']
|
21
23
|
end
|
data/lib/action_args.rb
CHANGED
@@ -3,8 +3,36 @@ module AbstractController
|
|
3
3
|
def send_action(method_name, *args)
|
4
4
|
return send method_name, *args unless args.blank?
|
5
5
|
|
6
|
-
values =
|
6
|
+
values = if defined? ActionController::StrongParameters
|
7
|
+
target_model_name = self.class.name.sub(/Controller$/, '').singularize.underscore.to_sym
|
8
|
+
permitted_attributes = self.class.instance_variable_get '@permitted_attributes'
|
9
|
+
method(method_name).parameters.reject {|kind, _| kind == :block }.map(&:last).map do |k|
|
10
|
+
if (k == target_model_name) && permitted_attributes
|
11
|
+
params.require(k).permit(*permitted_attributes)
|
12
|
+
else
|
13
|
+
params.require(k)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
else
|
17
|
+
method(method_name).parameters.reject {|kind, _| kind == :block }.map(&:last).map {|k| params[k]}
|
18
|
+
end
|
7
19
|
send method_name, *values
|
8
20
|
end
|
21
|
+
|
22
|
+
# You can configure StrongParameters' `permit` attributes using this DSL method.
|
23
|
+
# The `permit` call will be invoked only against parameters having the resource
|
24
|
+
# model name inferred from the controller class name.
|
25
|
+
#
|
26
|
+
# class UsersController < ApplicationController
|
27
|
+
# permits :name, :age
|
28
|
+
#
|
29
|
+
# def create(user)
|
30
|
+
# @user = User.new(user)
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
def self.permits(*attributes)
|
35
|
+
@permitted_attributes = attributes
|
36
|
+
end
|
9
37
|
end
|
10
38
|
end
|
data/lib/action_args/version.rb
CHANGED
@@ -5,6 +5,7 @@ require 'rails/generators/rails/scaffold_controller/scaffold_controller_generato
|
|
5
5
|
module Rails
|
6
6
|
module Generators
|
7
7
|
class ActionArgsScaffoldControllerGenerator < ::Rails::Generators::ScaffoldControllerGenerator
|
8
|
+
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
8
9
|
source_root File.expand_path('../templates', __FILE__)
|
9
10
|
end
|
10
11
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
3
|
class <%= controller_class_name %>Controller < ApplicationController
|
4
|
+
<% if defined? ActionController::StrongParameters -%>
|
5
|
+
permits <%= attributes.map {|a| ":#{a.name}" }.join(', ') %>
|
6
|
+
|
7
|
+
<% end -%>
|
4
8
|
# GET <%= route_url %>
|
5
9
|
def index
|
6
10
|
@<%= plural_table_name %> = <%= orm_class.all(class_name) %>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BooksController do
|
4
|
+
describe 'GET show' do
|
5
|
+
let(:rhg) { Book.create! title: 'RHG' }
|
6
|
+
before { get :show, :id => rhg.id }
|
7
|
+
subject { assigns :book }
|
8
|
+
it { should == rhg }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'POST create' do
|
12
|
+
let(:rhg) { Book.create! title: 'RHG' }
|
13
|
+
it { expect { post :create, :book => {title: 'AWDwR', price: 24} }.to change(Book, :count).by(1) }
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
if Rails::VERSION::MAJOR >= 4
|
4
|
+
describe StoresController do
|
5
|
+
describe 'GET show' do
|
6
|
+
let(:tatsu_zine) { Store.create! name: 'Tatsu-zine' }
|
7
|
+
before { get :show, :id => tatsu_zine.id }
|
8
|
+
subject { assigns :store }
|
9
|
+
it { should == tatsu_zine }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'POST create' do
|
13
|
+
it { expect { post :create, :store => {name: 'Tatsu-zine', url: 'http://tatsu-zine.com'} }.to change(Store, :count).by(1) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/spec/fake_app.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# config
|
2
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
3
|
+
|
4
|
+
module ActionArgsTestApp
|
5
|
+
class Application < Rails::Application
|
6
|
+
config.secret_token = [*'A'..'z'].join
|
7
|
+
config.session_store :cookie_store, :key => '_myapp_session'
|
8
|
+
config.active_support.deprecation = :log
|
9
|
+
config.eager_load = false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
ActionArgsTestApp::Application.initialize!
|
13
|
+
|
14
|
+
# routes
|
15
|
+
ActionArgsTestApp::Application.routes.draw do
|
16
|
+
resources :authors
|
17
|
+
resources :books
|
18
|
+
resources :stores
|
19
|
+
end
|
20
|
+
|
21
|
+
# models
|
22
|
+
class Author < ActiveRecord::Base
|
23
|
+
end
|
24
|
+
class Book < ActiveRecord::Base
|
25
|
+
end
|
26
|
+
class Store < ActiveRecord::Base
|
27
|
+
end
|
28
|
+
|
29
|
+
# helpers
|
30
|
+
module ApplicationHelper; end
|
31
|
+
|
32
|
+
# controllers
|
33
|
+
class ApplicationController < ActionController::Base
|
34
|
+
end
|
35
|
+
class AuthorsController < ApplicationController
|
36
|
+
def show
|
37
|
+
@author = Author.find params[:id]
|
38
|
+
render text: @author.name
|
39
|
+
end
|
40
|
+
end
|
41
|
+
class BooksController < ApplicationController
|
42
|
+
def show(id)
|
43
|
+
@book = Book.find(id)
|
44
|
+
render text: @book.title
|
45
|
+
end
|
46
|
+
|
47
|
+
def create(book)
|
48
|
+
book = book.permit :title, :price if Rails::VERSION::MAJOR >= 4
|
49
|
+
@book = Book.create! book
|
50
|
+
render text: @book.title
|
51
|
+
end
|
52
|
+
end
|
53
|
+
if Rails::VERSION::MAJOR >= 4
|
54
|
+
class StoresController < ApplicationController
|
55
|
+
permits :name, :url
|
56
|
+
|
57
|
+
def show(id)
|
58
|
+
@store = Store.find(id)
|
59
|
+
render text: @store.name
|
60
|
+
end
|
61
|
+
|
62
|
+
def create(store)
|
63
|
+
@store = Store.create! store
|
64
|
+
render text: @store.name
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# migrations
|
70
|
+
class CreateAllTables < ActiveRecord::Migration
|
71
|
+
def self.up
|
72
|
+
create_table(:authors) {|t| t.string :name}
|
73
|
+
create_table(:books) {|t| t.string :title; t.integer :price}
|
74
|
+
create_table(:stores) {|t| t.string :name; t.string :url}
|
75
|
+
end
|
76
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
# load Rails first
|
4
|
+
require 'rails'
|
5
|
+
require 'active_record'
|
6
|
+
require 'action_controller/railtie'
|
7
|
+
require 'action_args'
|
8
|
+
require 'fake_app'
|
9
|
+
require 'rspec/rails'
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.before :all do
|
13
|
+
CreateAllTables.up unless ActiveRecord::Base.connection.table_exists? 'authors'
|
14
|
+
end
|
15
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action_args
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,9 +9,25 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
13
|
-
dependencies:
|
14
|
-
|
12
|
+
date: 2012-11-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sqlite3
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Rails plugin gem that supports Merbish style controller action arguments.
|
15
31
|
email:
|
16
32
|
- ronnie@dio.jp
|
17
33
|
executables: []
|
@@ -19,11 +35,14 @@ extensions: []
|
|
19
35
|
extra_rdoc_files: []
|
20
36
|
files:
|
21
37
|
- .gitignore
|
38
|
+
- .travis.yml
|
22
39
|
- Gemfile
|
23
40
|
- MIT-LICENSE
|
24
41
|
- README.rdoc
|
25
42
|
- Rakefile
|
26
43
|
- action_args.gemspec
|
44
|
+
- gemfiles/rails_32.gemfile
|
45
|
+
- gemfiles/rails_40.gemfile
|
27
46
|
- lib/action_args.rb
|
28
47
|
- lib/action_args/abstract_controller.rb
|
29
48
|
- lib/action_args/version.rb
|
@@ -31,6 +50,11 @@ files:
|
|
31
50
|
- lib/generators/action_args/rspec/scaffold/templates/action_args_controller_spec.rb
|
32
51
|
- lib/generators/rails/action_args_scaffold_controller_generator.rb
|
33
52
|
- lib/generators/rails/templates/controller.rb
|
53
|
+
- spec/controllers/action_args_controller_spec.rb
|
54
|
+
- spec/controllers/ordinal_controller_spec.rb
|
55
|
+
- spec/controllers/strong_parameters_spec.rb
|
56
|
+
- spec/fake_app.rb
|
57
|
+
- spec/spec_helper.rb
|
34
58
|
homepage: http://asakusa.rubyist.net/
|
35
59
|
licenses: []
|
36
60
|
post_install_message:
|
@@ -51,8 +75,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
75
|
version: '0'
|
52
76
|
requirements: []
|
53
77
|
rubyforge_project: action_args
|
54
|
-
rubygems_version: 1.8.
|
78
|
+
rubygems_version: 1.8.24
|
55
79
|
signing_key:
|
56
80
|
specification_version: 3
|
57
|
-
summary: Controller action arguments parameterizer for Rails 3
|
58
|
-
test_files:
|
81
|
+
summary: Controller action arguments parameterizer for Rails 3+ & Ruby 1.9+
|
82
|
+
test_files:
|
83
|
+
- spec/controllers/action_args_controller_spec.rb
|
84
|
+
- spec/controllers/ordinal_controller_spec.rb
|
85
|
+
- spec/controllers/strong_parameters_spec.rb
|
86
|
+
- spec/fake_app.rb
|
87
|
+
- spec/spec_helper.rb
|