cancan_strong_parameters 0.1.3 → 0.1.4
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/README.md +4 -0
- data/Rakefile +9 -0
- data/cancan_strong_parameters.gemspec +6 -0
- data/lib/cancan_strong_parameters/controller.rb +137 -0
- data/lib/cancan_strong_parameters/deep_permit.rb +15 -0
- data/lib/cancan_strong_parameters/rails/controller/base.rb +3 -112
- data/lib/cancan_strong_parameters/version.rb +1 -1
- data/lib/cancan_strong_parameters.rb +3 -1
- data/test/app/controllers/posts_controller.rb +16 -0
- data/test/app/models/post.rb +6 -0
- data/test/config.ru +1 -0
- data/test/rails_helper.rb +37 -0
- data/test/script/rails +1 -0
- data/test/test_cancan_strong_parameters.rb +45 -0
- metadata +97 -3
data/.gitignore
CHANGED
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -10,6 +10,12 @@ Gem::Specification.new do |gem|
|
|
10
10
|
|
11
11
|
gem.add_dependency "cancan"
|
12
12
|
gem.add_dependency "strong_parameters"
|
13
|
+
gem.add_dependency "activesupport"
|
14
|
+
|
15
|
+
gem.add_development_dependency "require_all"
|
16
|
+
gem.add_development_dependency "minitest", "~> 3.0"
|
17
|
+
gem.add_development_dependency "rails"
|
18
|
+
gem.add_development_dependency "debugger"
|
13
19
|
|
14
20
|
gem.files = `git ls-files`.split($\)
|
15
21
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module CancanStrongParameters
|
2
|
+
module Controller
|
3
|
+
|
4
|
+
HASH_DEFAULTS = [:_destroy, :_delete]
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
# Use this with CanCan's load_resource to permit a set of params before
|
8
|
+
# it tries to build or update a resource with them.
|
9
|
+
#
|
10
|
+
# Usage:
|
11
|
+
# class BooksController < ApplicationController
|
12
|
+
# load_resource :book
|
13
|
+
# permit_params book: [:title, :isbn]
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# Or:
|
17
|
+
# class BooksController < ApplicationController
|
18
|
+
# load_resource
|
19
|
+
# permit_params :title, :isbn
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# the second form should work in the simple case where you don't have to
|
23
|
+
# supply a resource name for #load_resource
|
24
|
+
#
|
25
|
+
def permit_params *keys
|
26
|
+
filter_strong_params :permit, [:create, :update], keys
|
27
|
+
end
|
28
|
+
|
29
|
+
# Like permit_params, but only applies to create action
|
30
|
+
#
|
31
|
+
def permit_params_on_create *keys
|
32
|
+
filter_strong_params :permit, :create, keys
|
33
|
+
end
|
34
|
+
|
35
|
+
# Like permit_params, but only applies to update action
|
36
|
+
#
|
37
|
+
def permit_params_on_update *keys
|
38
|
+
filter_strong_params :permit, :update, keys
|
39
|
+
end
|
40
|
+
|
41
|
+
# Like permit_params, but marks the params required
|
42
|
+
#
|
43
|
+
def require_params *keys
|
44
|
+
filter_strong_params :require, [:create, :update], keys
|
45
|
+
end
|
46
|
+
|
47
|
+
# Like require_params, but only applies to create action
|
48
|
+
#
|
49
|
+
def require_params_on_create *keys
|
50
|
+
filter_strong_params :require, :create, keys
|
51
|
+
end
|
52
|
+
|
53
|
+
# Like require_params, but only applies to update action
|
54
|
+
#
|
55
|
+
def require_params_on_update *keys
|
56
|
+
filter_strong_params :require, :update, keys
|
57
|
+
end
|
58
|
+
|
59
|
+
# Does a permit! at every level of the params to let everything through
|
60
|
+
#
|
61
|
+
def permit_all_params options = {}
|
62
|
+
prepend_before_filter options.reverse_merge(:only => [:create, :update]) do
|
63
|
+
self.params.deep_permit!
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def filter_strong_params method, actions, keys # :nodoc:
|
68
|
+
hash = keys.extract_options!
|
69
|
+
keys.flatten!
|
70
|
+
|
71
|
+
# Handle attributes if permitted attributes are given for nested models
|
72
|
+
if (hash.present? && keys.present?) || (hash.select{|k,v| v.is_a?(Array)} == hash)
|
73
|
+
|
74
|
+
@@defaults = CancanStrongParameters::Controller::HASH_DEFAULTS
|
75
|
+
@@hash = hash.attributized
|
76
|
+
|
77
|
+
prepend_before_filter :only => actions do
|
78
|
+
resource_name = self.class.resource_name
|
79
|
+
self.params[resource_name] = params[resource_name].send method, *[*keys.flatten + @@defaults, @@hash]
|
80
|
+
end
|
81
|
+
elsif hash.present?
|
82
|
+
prepend_before_filter :only => actions do
|
83
|
+
self.params.merge! params.send(method, hash)
|
84
|
+
end
|
85
|
+
else
|
86
|
+
prepend_before_filter :only => actions do
|
87
|
+
resource_name = self.class.resource_name
|
88
|
+
if params.has_key?(resource_name)
|
89
|
+
self.params[resource_name] = params[resource_name].send method, *keys
|
90
|
+
else
|
91
|
+
self.params = params.send method, *keys
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def resource_name
|
98
|
+
self.to_s.sub("Controller", "").underscore.split('/').last.singularize
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.included(base)
|
103
|
+
base.extend(ClassMethods)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class Hash
|
110
|
+
|
111
|
+
# Converts keys with hash values -- e.g. posts: {} -- to posts_attributes for nested forms.
|
112
|
+
#
|
113
|
+
# Also, Allows rails specific values like _destroy or _delete.
|
114
|
+
#
|
115
|
+
# NOTE: You must enable `allow_destroy: true` in your call to `accepts_nested_attributes_for` anyway,
|
116
|
+
# so this is secure to whitelist here.
|
117
|
+
def attributized
|
118
|
+
defaults = CancanStrongParameters::Controller::HASH_DEFAULTS
|
119
|
+
|
120
|
+
Hash.new.tap do |h|
|
121
|
+
self.each do |k,v|
|
122
|
+
h[:"#{k}_attributes"] = self.delete(k).attributized + defaults
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class Array
|
129
|
+
def attributized
|
130
|
+
Array.new.tap do |a|
|
131
|
+
self.each do |v|
|
132
|
+
v = v.attributized if v.is_a?(Hash)
|
133
|
+
a << v
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module CancanStrongParameters
|
2
|
+
module DeepPermit
|
3
|
+
def deep_permit!
|
4
|
+
self.each do |key, value|
|
5
|
+
if value.is_a?(Hash)
|
6
|
+
if !value.respond_to?(:permit!)
|
7
|
+
self[key] = value = ActionController::Parameters.new(value)
|
8
|
+
end
|
9
|
+
value.deep_permit!
|
10
|
+
end
|
11
|
+
end
|
12
|
+
permit!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,116 +1,7 @@
|
|
1
1
|
class ActionController::Base
|
2
|
-
|
3
|
-
# it tries to build or update a resource with them.
|
4
|
-
#
|
5
|
-
# Usage:
|
6
|
-
# class BooksController < ApplicationController
|
7
|
-
# load_resource :book
|
8
|
-
# permit_params book: [:title, :isbn]
|
9
|
-
# end
|
10
|
-
#
|
11
|
-
# Or:
|
12
|
-
# class BooksController < ApplicationController
|
13
|
-
# load_resource
|
14
|
-
# permit_params :title, :isbn
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# the second form should work in the simple case where you don't have to
|
18
|
-
# supply a resource name for #load_resource
|
19
|
-
#
|
20
|
-
def self.permit_params *keys
|
21
|
-
filter_strong_params :permit, [:create, :update], keys
|
22
|
-
end
|
23
|
-
|
24
|
-
# Like permit_params, but only applies to create action
|
25
|
-
#
|
26
|
-
def self.permit_params_on_create *keys
|
27
|
-
filter_strong_params :permit, :create, keys
|
28
|
-
end
|
29
|
-
|
30
|
-
# Like permit_params, but only applies to update action
|
31
|
-
#
|
32
|
-
def self.permit_params_on_update *keys
|
33
|
-
filter_strong_params :permit, :update, keys
|
34
|
-
end
|
35
|
-
|
36
|
-
# Like permit_params, but marks the params required
|
37
|
-
#
|
38
|
-
def self.require_params *keys
|
39
|
-
filter_strong_params :require, [:create, :update], keys
|
40
|
-
end
|
41
|
-
|
42
|
-
# Like require_params, but only applies to create action
|
43
|
-
#
|
44
|
-
def self.require_params_on_create *keys
|
45
|
-
filter_strong_params :require, :create, keys
|
46
|
-
end
|
47
|
-
|
48
|
-
# Like require_params, but only applies to update action
|
49
|
-
#
|
50
|
-
def self.require_params_on_update *keys
|
51
|
-
filter_strong_params :require, :update, keys
|
52
|
-
end
|
53
|
-
|
54
|
-
# Does a permit! at every level of the params to let everything through
|
55
|
-
#
|
56
|
-
def self.permit_all_params options = {}
|
57
|
-
prepend_before_filter options.reverse_merge(:only => [:create, :update]) do
|
58
|
-
self.params.deep_permit!
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.filter_strong_params method, actions, keys # :nodoc:
|
63
|
-
hash = keys.extract_options!
|
64
|
-
keys.flatten!
|
65
|
-
|
66
|
-
# Handle attributes if permitted attributes are given for nested models
|
67
|
-
if (hash.present? && keys.present?) || (hash.select{|k,v| v.is_a?(Array)} == hash)
|
68
|
-
prepend_before_filter :only => actions do
|
69
|
-
resource_name = self.class.resource_name
|
70
|
-
hash = self.class.attributized(hash)
|
71
|
-
self.params[resource_name] = params[resource_name].send method, *[*keys.flatten, hash]
|
72
|
-
end
|
73
|
-
elsif hash.present?
|
74
|
-
prepend_before_filter :only => actions do
|
75
|
-
self.params.merge! params.send(method, hash)
|
76
|
-
end
|
77
|
-
else
|
78
|
-
prepend_before_filter :only => actions do
|
79
|
-
resource_name = self.class.resource_name
|
80
|
-
if params.has_key?(resource_name)
|
81
|
-
self.params[resource_name] = params[resource_name].send method, *keys
|
82
|
-
else
|
83
|
-
self.params = params.send method, *keys
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.resource_name
|
90
|
-
self.to_s.sub("Controller", "").underscore.split('/').last.singularize
|
91
|
-
end
|
92
|
-
|
93
|
-
def self.attributized(hash)
|
94
|
-
Hash.new.tap do |h|
|
95
|
-
hash.each do |k,v|
|
96
|
-
h[:"#{k}_attributes"] = v
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
2
|
+
include CancanStrongParameters::Controller
|
100
3
|
end
|
101
4
|
|
102
|
-
|
103
|
-
|
104
|
-
def deep_permit!
|
105
|
-
self.each do |key, value|
|
106
|
-
if value.is_a?(Hash)
|
107
|
-
if !value.respond_to?(:permit!)
|
108
|
-
self[key] = value = ActionController::Parameters.new(value)
|
109
|
-
end
|
110
|
-
value.deep_permit!
|
111
|
-
end
|
112
|
-
end
|
113
|
-
permit!
|
114
|
-
end
|
115
|
-
end
|
5
|
+
class ActionController::Parameters
|
6
|
+
include CancanStrongParameters::DeepPermit
|
116
7
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require "cancan_strong_parameters/version"
|
2
|
-
require "cancan_strong_parameters/
|
2
|
+
require "cancan_strong_parameters/controller"
|
3
|
+
require "cancan_strong_parameters/deep_permit"
|
4
|
+
require "cancan_strong_parameters/rails/controller/base" if defined?(Rails)
|
3
5
|
|
4
6
|
module CancanStrongParameters
|
5
7
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class PostsController < ActionController::Base
|
2
|
+
include CancanStrongParameters::Controller
|
3
|
+
|
4
|
+
permit_params :title, :content,
|
5
|
+
comments: [
|
6
|
+
:body, tags: [:name]
|
7
|
+
]
|
8
|
+
|
9
|
+
def create
|
10
|
+
@post = Post.new(params[:post])
|
11
|
+
@post_attributes = params[:post]
|
12
|
+
render json: @post
|
13
|
+
end
|
14
|
+
alias_method :update, :create
|
15
|
+
|
16
|
+
end
|
data/test/config.ru
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Empty to make tests work
|
@@ -0,0 +1,37 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
ENV["RAILS_ENV"] ||= 'test'
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
|
8
|
+
require 'debugger'
|
9
|
+
|
10
|
+
gem 'actionpack', '>= 3.0.0'
|
11
|
+
gem 'activesupport', '>= 3.0.0'
|
12
|
+
gem 'activemodel', '>= 3.0.0'
|
13
|
+
gem 'railties', '>= 3.0.0'
|
14
|
+
|
15
|
+
# Only the parts of rails we want to use
|
16
|
+
# if you want everything, use "rails/all"
|
17
|
+
require "action_controller/railtie"
|
18
|
+
require "active_model/railtie"
|
19
|
+
require "rails/test_unit/railtie"
|
20
|
+
require "rack/test"
|
21
|
+
|
22
|
+
root = File.expand_path(File.dirname(__FILE__))
|
23
|
+
|
24
|
+
# Define the application and configuration
|
25
|
+
module Config
|
26
|
+
class Application < ::Rails::Application
|
27
|
+
# configuration here if needed
|
28
|
+
config.active_support.deprecation = :stderr
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Initialize the application
|
33
|
+
Config::Application.initialize!
|
34
|
+
|
35
|
+
Config::Application.routes.draw do
|
36
|
+
resources :posts
|
37
|
+
end
|
data/test/script/rails
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Empty to make tests work
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
require 'require_all'
|
4
|
+
|
5
|
+
require 'strong_parameters'
|
6
|
+
require 'cancan_strong_parameters'
|
7
|
+
|
8
|
+
## Boot up an instance of rails
|
9
|
+
require 'rails_helper'
|
10
|
+
require 'rails/test_help'
|
11
|
+
|
12
|
+
class PostsControllerTest < ActionController::TestCase
|
13
|
+
test "should not clip off deep params" do
|
14
|
+
params = {
|
15
|
+
post: {
|
16
|
+
title: "Title of post",
|
17
|
+
content: "Post main content.",
|
18
|
+
comments_attributes: [{
|
19
|
+
body: "My comment.",
|
20
|
+
tags_attributes: [{
|
21
|
+
name: "article"
|
22
|
+
}]
|
23
|
+
}]
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
post :create, params
|
28
|
+
assert_equal \
|
29
|
+
ActiveSupport::HashWithIndifferentAccess.new(assigns(:post_attributes)),
|
30
|
+
ActiveSupport::HashWithIndifferentAccess.new(params[:post])
|
31
|
+
end
|
32
|
+
|
33
|
+
test "keeps _destroy keys" do
|
34
|
+
params = {
|
35
|
+
post: {
|
36
|
+
_destroy: true
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
put :update, {id: 1}.merge(params)
|
41
|
+
assert_equal \
|
42
|
+
ActiveSupport::HashWithIndifferentAccess.new(assigns(:post_attributes)),
|
43
|
+
ActiveSupport::HashWithIndifferentAccess.new(params[:post])
|
44
|
+
end
|
45
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cancan_strong_parameters
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
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: 2012-10-
|
12
|
+
date: 2012-10-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cancan
|
@@ -43,6 +43,86 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: activesupport
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: require_all
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: minitest
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '3.0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '3.0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rails
|
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'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: debugger
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
46
126
|
description: make CanCan work with strong_parameters
|
47
127
|
email:
|
48
128
|
- me@colinyoung.com
|
@@ -57,8 +137,16 @@ files:
|
|
57
137
|
- Rakefile
|
58
138
|
- cancan_strong_parameters.gemspec
|
59
139
|
- lib/cancan_strong_parameters.rb
|
140
|
+
- lib/cancan_strong_parameters/controller.rb
|
141
|
+
- lib/cancan_strong_parameters/deep_permit.rb
|
60
142
|
- lib/cancan_strong_parameters/rails/controller/base.rb
|
61
143
|
- lib/cancan_strong_parameters/version.rb
|
144
|
+
- test/app/controllers/posts_controller.rb
|
145
|
+
- test/app/models/post.rb
|
146
|
+
- test/config.ru
|
147
|
+
- test/rails_helper.rb
|
148
|
+
- test/script/rails
|
149
|
+
- test/test_cancan_strong_parameters.rb
|
62
150
|
homepage: https://github.com/colinyoung/cancan_strong_parameters
|
63
151
|
licenses: []
|
64
152
|
post_install_message:
|
@@ -83,5 +171,11 @@ rubygems_version: 1.8.24
|
|
83
171
|
signing_key:
|
84
172
|
specification_version: 3
|
85
173
|
summary: make CanCan work with strong_parameters
|
86
|
-
test_files:
|
174
|
+
test_files:
|
175
|
+
- test/app/controllers/posts_controller.rb
|
176
|
+
- test/app/models/post.rb
|
177
|
+
- test/config.ru
|
178
|
+
- test/rails_helper.rb
|
179
|
+
- test/script/rails
|
180
|
+
- test/test_cancan_strong_parameters.rb
|
87
181
|
has_rdoc:
|