cancan_strong_parameters 0.2.1 → 0.2.2

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
@@ -16,4 +16,5 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .DS_Store
19
- log/
19
+ log/
20
+ test/log/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
5
+ - 1.8.7
data/README.md CHANGED
@@ -1,14 +1,12 @@
1
1
  # CancanStrongParameters
2
2
 
3
- CanCan and [strong_parameters](https://github.com/rails/strong_parameters) are friends now!
3
+ [CanCan](ryanb/cancan) and [strong_parameters](rails/strong_parameters) are friends now!
4
4
 
5
5
  [![Build Status](https://secure.travis-ci.org/colinyoung/cancan_strong_parameters.png)](http://travis-ci.org/colinyoung/cancan_strong_parameters)
6
6
 
7
7
  ## Authors
8
8
 
9
- The majority of this gem is credited to @mckeed, who posted this gist: https://gist.github.com/2878508
10
- I (@colinyoung) helped put some of it together.
11
-
9
+ The majority of this gem is credited to @mckeed, who posted this gist: https://gist.github.com/2878508. I (@colinyoung) helped put some of it together.
12
10
 
13
11
  ## Installation
14
12
 
@@ -26,14 +24,40 @@ Or install it yourself as:
26
24
 
27
25
  ## Usage
28
26
 
29
- 1. Add it to your Gemfile
30
- 2. Wherever you use `load_and_authorize_resource`, also add:
31
-
32
- class PostsController < ApplicationController
33
- ...
34
- load_and_authorize_resource
35
- permit_params post: [:name, :title, author: {:name}]
36
- end
27
+ 1. Add `gem "cancan_strong_parameters"` to your Gemfile
28
+ 2. Wherever you use `load_and_authorize_resource`, also permit your parameters:
29
+
30
+ ```ruby
31
+ class PostsController < ApplicationController
32
+ ...
33
+ load_and_authorize_resource
34
+
35
+ permit_params :body, tags: [:name]
36
+ # --> permit_params allows parameters but doesn't require them.
37
+ # In the preceding, :tags are a nested resource of post, while
38
+ # :body is an attribute of a Post.
39
+ #
40
+ # :tags is plural here because it's a has_many association, but
41
+ # you should use a singular key for a has_one.
42
+
43
+ require_params :title
44
+ # --> require_params works exactly the same, but throws an error
45
+ # if the parameter isn't provided.
46
+
47
+ # You can also require/permit params on create or update only:
48
+ permit_params_on_create ...
49
+ permit_params_on_update ...
50
+ require_params_on_create ...
51
+ end
52
+ ```
53
+ 3. Finally, don't forget to make the vars you use in your controllers
54
+ accessible in your models:
55
+
56
+ ```ruby
57
+ class Post < ActiveRecord::Base
58
+ attr_accessible :title, :body, :tags_attributes
59
+ end
60
+ ```
37
61
 
38
62
  ## Testing
39
63
 
@@ -49,6 +73,7 @@ Run with `bundle exec rake test`.
49
73
 
50
74
  ## Changelog
51
75
 
76
+ * Fixed docs to be compatible with 0.1.5.
52
77
  * Fixed some issues with nested form subfields in `permit_params`
53
78
  * Made compatible for nested forms
54
79
  * Added default allows for _destroy.
@@ -14,8 +14,8 @@ Gem::Specification.new do |gem|
14
14
 
15
15
  gem.add_development_dependency "require_all"
16
16
  gem.add_development_dependency "minitest", "~> 3.0"
17
+ gem.add_development_dependency "minitest_tu_shim"
17
18
  gem.add_development_dependency "rails"
18
- gem.add_development_dependency "debugger"
19
19
 
20
20
  gem.files = `git ls-files`.split($\)
21
21
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -1,4 +1,4 @@
1
- require "active_support/hash_with_indifferent_access"
1
+ require "cancan_strong_parameters/ruby/hash"
2
2
  require "cancan_strong_parameters/version"
3
3
  require "cancan_strong_parameters/controller"
4
4
  require "cancan_strong_parameters/deep_permit"
@@ -1,7 +1,7 @@
1
1
  module CancanStrongParameters
2
2
  module Controller
3
3
 
4
- HASH_DEFAULTS = [:id, :_destroy, :_delete]
4
+ HASH_DEFAULTS = ['id', '_destroy', '_delete']
5
5
 
6
6
  module ClassMethods
7
7
  # Use this with CanCan's load_resource to permit a set of params before
@@ -72,11 +72,24 @@ module CancanStrongParameters
72
72
  if (hash.present? && keys.present?) || (hash.select{|k,v| v.is_a?(Array)} == hash)
73
73
 
74
74
  defaults = CancanStrongParameters::Controller::HASH_DEFAULTS
75
- hash = hash.attributized
75
+
76
+ # @todo We have to stringify everything for 1.8.7 due to a bug in `strong_parameters`.
77
+ # More at https://github.com/rails/strong_parameters/pull/51
78
+ hash = hash.attributized.stringified
76
79
 
77
80
  prepend_before_filter :only => actions do
78
81
  resource_name = self.class.resource_name
79
- self.params[resource_name] = params[resource_name].standardized.send method, *[*keys.flatten + defaults, hash]
82
+
83
+ # @todo We have to stringify everything for 1.8.7 due to a bug in `strong_parameters`.
84
+ # More at https://github.com/rails/strong_parameters/pull/51
85
+ parameters = keys.flatten.map! {|k| k.to_s } + defaults
86
+ parameters << ActionController::Parameters.new(hash)
87
+
88
+ # original: parameters = keys.flatten + defaults
89
+ # parameters << hash
90
+ return warn("Not updating - no parameters key present for #{resource_name}") unless params[resource_name]
91
+
92
+ self.params[resource_name] = params[resource_name].standardized.send method, *parameters
80
93
  end
81
94
  elsif hash.present?
82
95
  prepend_before_filter :only => actions do
@@ -86,9 +99,9 @@ module CancanStrongParameters
86
99
  prepend_before_filter :only => actions do
87
100
  resource_name = self.class.resource_name
88
101
  if params.has_key?(resource_name)
89
- self.params[resource_name] = params[resource_name].send method, *keys
102
+ self.params[resource_name] = params[resource_name].send method, *keys.stringified
90
103
  else
91
- self.params = params.send method, *keys
104
+ self.params = params.send method, *keys.stringified
92
105
  end
93
106
  end
94
107
  end
@@ -106,6 +119,12 @@ module CancanStrongParameters
106
119
  def self.included(base)
107
120
  base.extend(ClassMethods)
108
121
  end
122
+
123
+ # Errors
124
+ def warn msg
125
+ return unless Rails and Rails.logger
126
+ Rails.logger.warn(msg)
127
+ end
109
128
 
110
129
  end
111
130
  end
@@ -184,4 +203,39 @@ class String
184
203
  def is_hex?
185
204
  !!(self =~ /^[0-9a-f]+$/)
186
205
  end
206
+ end
207
+
208
+ # @todo Can be remove when new version of `strong_parameters` (>=0.1.5) is released.
209
+ class Hash
210
+ def stringified
211
+ Hash.new.tap do |h|
212
+ each do |key, value|
213
+ value = case value
214
+ when Symbol
215
+ value.to_s
216
+ when Hash
217
+ value.indifferent
218
+ when Array
219
+ value.stringified
220
+ end
221
+ h[key.to_s] = value
222
+ end
223
+ end
224
+ end
225
+ end
226
+
227
+ class Array
228
+ def stringified
229
+ Array.new.tap do |a|
230
+ each do |value|
231
+ value = if value.is_a? Hash
232
+ value.stringified.indifferent
233
+ else
234
+ value.to_s
235
+ end
236
+
237
+ a << value
238
+ end
239
+ end
240
+ end
187
241
  end
@@ -0,0 +1,8 @@
1
+ require "active_support/hash_with_indifferent_access"
2
+
3
+ class Hash
4
+ def indifferent
5
+ ActiveSupport::HashWithIndifferentAccess.new(self)
6
+ end
7
+ alias :indifferent_access :indifferent
8
+ end
@@ -1,3 +1,3 @@
1
1
  module CancanStrongParameters
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -2,22 +2,23 @@ class PostsController < ActionController::Base
2
2
  include CancanStrongParameters::Controller
3
3
 
4
4
  permit_params :title, :content,
5
- comments: [
6
- :body, tags: [:name]
5
+ :comments => [
6
+ :body,
7
+ { :tags => [ :name ] } # This is fugly, use 1.9!
7
8
  ]
8
9
 
9
10
  def create
10
11
  @post = Post.new(params[:post])
11
12
  @post_attributes = params[:post]
12
- render json: @post
13
+ render :json => @post
13
14
  end
14
15
 
15
16
  def update
16
17
  @post = Post.find(params[:id])
17
18
  if @post.update_attributes(params[:post])
18
- render json: @post
19
+ render :json => @post
19
20
  else
20
- render json: { errors: @post.errors.full_messages }, status: :unprocessable_entity
21
+ render :json => { :errors => post.errors.full_messages }, :status => :unprocessable_entity
21
22
  end
22
23
  end
23
24
 
@@ -12,7 +12,7 @@ class Post
12
12
 
13
13
  # Fake persistence
14
14
  def self.sample_post
15
- new(title: "Sample post", body: "Sample body")
15
+ new(:title => "Sample post", :body => "Sample body")
16
16
  end
17
17
 
18
18
  def self.find(*args)
@@ -0,0 +1,60 @@
1
+ module MiniTest::Expectations
2
+ def assert_same_content(item, other_item, verb=:assert)
3
+ item.each do |attrs|
4
+ value = attrs.last
5
+ key = attrs.first if attrs.length > 1
6
+
7
+
8
+ other_value = other_item[key] if self.is_a?(Hash)
9
+
10
+ if other_value.present?
11
+ if value.respond_to? :same_as?
12
+ send verb, value.same_as?(other_value), "#{value} was not same as #{other_value}."
13
+ else
14
+ send "#{verb}_equal", value, other_value
15
+ end
16
+ else
17
+ send verb, item.same_as?(other_item), "#{item} was not the same as #{other_item}."
18
+ end
19
+ end
20
+ end
21
+
22
+ def refute_same_content(item, other_item)
23
+ assert_same_content(item, other_item, :refute)
24
+ end
25
+ end
26
+
27
+ class Array
28
+ def same_as?(other_ary)
29
+ cpy = dup
30
+ other_cpy = other_ary.dup
31
+ each do |item|
32
+ case item
33
+ when Array, Hash
34
+ cpy.delete(item) if other_ary.any? { |other_item| other_item.same_as?(item) && other_cpy.delete(other_item) }
35
+ else
36
+ cpy.delete(item) if other_ary.include?(item) && other_cpy.delete(item)
37
+ end
38
+ end
39
+
40
+ cpy.empty? and other_cpy.empty?
41
+ end
42
+ end
43
+
44
+ class Hash
45
+ def same_as?(other_hsh)
46
+ return false unless self.keys.count == other_hsh.keys.count
47
+ each do |key, value|
48
+ return false unless other_hsh.has_key? key
49
+
50
+ other_value = other_hsh[key]
51
+ if value.respond_to? :same_as?
52
+ return false unless value.same_as? other_value
53
+ else
54
+ return false unless value == other_value
55
+ end
56
+ end
57
+
58
+ true
59
+ end
60
+ end
data/test/config.ru CHANGED
@@ -1 +1 @@
1
- # Empty to make tests work
1
+ # Empty to make tests work
@@ -1,101 +1,97 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class PostsControllerTest < ActionController::TestCase
4
+
4
5
  test "should not clip off deep params" do
5
6
  params = {
6
- post: {
7
- title: "Title of post",
8
- content: "Post main content.",
9
- comments_attributes: [{
10
- body: "My comment.",
11
- tags_attributes: [{
12
- name: "article"
7
+ :post => {
8
+ :title => "Title of post",
9
+ :content => "Post main content.",
10
+ :comments_attributes => [{
11
+ :body => "My comment.",
12
+ :tags_attributes => [{
13
+ :name => "article"
13
14
  }]
14
15
  }]
15
16
  }
16
17
  }
17
18
 
18
19
  post :create, params
19
- assert_equal \
20
- ActiveSupport::HashWithIndifferentAccess.new(assigns(:post_attributes)),
21
- ActiveSupport::HashWithIndifferentAccess.new(params[:post])
20
+ assigns(:post_attributes).indifferent.must_have_same_content_as params[:post].indifferent
22
21
  end
23
22
 
24
23
  test "keeps _destroy keys" do
25
24
  params = {
26
- post: {
27
- _destroy: true
25
+ :post => {
26
+ :_destroy => true
28
27
  }
29
28
  }
30
29
 
31
30
  post :create, params
32
- assert_equal \
33
- ActiveSupport::HashWithIndifferentAccess.new(assigns(:post_attributes)),
34
- ActiveSupport::HashWithIndifferentAccess.new(params[:post])
31
+ assigns(:post_attributes).indifferent.must_have_same_content_as params[:post].indifferent
35
32
  end
36
33
 
37
34
  test "can handle multiple items" do
38
35
  params = {
39
- post: {
40
- title: "Hello",
41
- comments_attributes: {
36
+ :post => {
37
+ :title => "Hello",
38
+ :comments_attributes => {
42
39
  "0" => {
43
- body: "Comment 1",
44
- tags_attributes: {
40
+ :body => "Comment 1",
41
+ :tags_attributes => {
45
42
  "0" => {
46
- name: "article"
43
+ :name => "article"
47
44
  },
48
45
  "1" => {
49
- name: "post"
46
+ :name => "post"
50
47
  },
51
48
  }
52
49
  },
53
50
  "1" => {
54
- body: "Comment 2"
51
+ :body => "Comment 2"
55
52
  },
56
53
  "new_3904949" => {
57
- body: "Comment 3"
54
+ :body => "Comment 3"
58
55
  }
59
56
  }
60
57
  }
61
58
  }
62
59
 
63
60
  post :create, params
64
- assert_equal \
65
- ActiveSupport::HashWithIndifferentAccess.new(assigns(:post_attributes)),
66
- ActiveSupport::HashWithIndifferentAccess.new({
67
- title: "Hello",
68
- comments_attributes: [
69
- {
70
- body: "Comment 1",
71
- tags_attributes: [{
72
- name: "article"
73
- },
74
- {
75
- name: "post"
76
- }
77
- ]
78
- },
79
- {
80
- body: "Comment 2"
81
- },
82
- {
83
- body: "Comment 3"
84
- }
85
- ]
86
- })
61
+ expected = {
62
+ :title => "Hello",
63
+ :comments_attributes => [
64
+ {
65
+ :body => "Comment 1",
66
+ :tags_attributes => [{
67
+ :name => "post"
68
+ },
69
+ {
70
+ :name => "article"
71
+ }
72
+ ]
73
+ },
74
+ {
75
+ :body => "Comment 2"
76
+ },
77
+ {
78
+ :body => "Comment 3"
79
+ }
80
+ ]
81
+ }
82
+ assigns(:post_attributes).must_have_same_content_as expected.indifferent
87
83
  end
88
84
 
89
- test "can handle multiple items but with only new itesm" do
85
+ test "can handle multiple items but with only new items" do
90
86
  params = {
91
- post: {
92
- title: "Hello",
93
- comments_attributes: {
87
+ :post => {
88
+ :title => "Hello",
89
+ :comments_attributes => {
94
90
  "new_3904949" => {
95
- body: "Comment 3",
96
- tags_attributes: {
91
+ :body => "Comment 3",
92
+ :tags_attributes => {
97
93
  "new_23040234" => {
98
- name: "article"
94
+ :name => "article"
99
95
  }
100
96
  }
101
97
  }
@@ -104,16 +100,15 @@ class PostsControllerTest < ActionController::TestCase
104
100
  }
105
101
 
106
102
  post :create, params
107
- assert_equal \
108
- ActiveSupport::HashWithIndifferentAccess.new(assigns(:post_attributes)),
109
- ActiveSupport::HashWithIndifferentAccess.new({
110
- title: "Hello",
111
- comments_attributes: [{
112
- body: "Comment 3",
113
- tags_attributes: [{
114
- name: "article"
115
- }]
103
+ expected = {
104
+ :title => "Hello",
105
+ :comments_attributes => [{
106
+ :body => "Comment 3",
107
+ :tags_attributes => [{
108
+ :name => "article"
116
109
  }]
117
- })
110
+ }]
111
+ }
112
+ assigns(:post_attributes).indifferent.must_have_same_content_as expected.indifferent
118
113
  end
119
114
  end
@@ -6,9 +6,9 @@ class TitleControllerTest < ActionController::TestCase
6
6
 
7
7
  new_title = 'Changed title'
8
8
  put :update,
9
- id: 1,
10
- post: {
11
- title: new_title
9
+ :id => 1,
10
+ :post => {
11
+ :title => new_title
12
12
  }
13
13
 
14
14
  assert_equal assigns[:post].title, new_title
data/test/rails_helper.rb CHANGED
@@ -5,8 +5,6 @@ ENV["RAILS_ENV"] ||= 'test'
5
5
 
6
6
  require 'rubygems'
7
7
 
8
- require 'debugger'
9
-
10
8
  gem 'actionpack', '>= 3.0.0'
11
9
  gem 'activesupport', '>= 3.0.0'
12
10
  gem 'activemodel', '>= 3.0.0'
@@ -35,5 +33,5 @@ Config::Application.initialize!
35
33
  Config::Application.routes.draw do
36
34
  resources :posts
37
35
 
38
- match 'title/:id', to: 'title#update', via: :put
36
+ match 'title/:id', :to => 'title#update', :via => :put
39
37
  end
data/test/test_helper.rb CHANGED
@@ -8,3 +8,11 @@ require 'cancan_strong_parameters'
8
8
  ## Boot up an instance of rails
9
9
  require 'rails_helper'
10
10
  require 'rails/test_help'
11
+
12
+ ## Custom matchers
13
+ require 'assertions/assert_same_content'
14
+
15
+ module MiniTest::Expectations
16
+ infect_an_assertion :assert_same_content, :must_have_same_content_as
17
+ infect_an_assertion :refute_same_content, :wont_have_same_content_as
18
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+
3
+ class SameContentTest < Test::Unit::TestCase
4
+
5
+ def test_same_content_works
6
+ ['a', 'b', 'c'].must_have_same_content_as ['b', 'a', 'c']
7
+ ['a', 'b', 'c'].wont_have_same_content_as ['b', 'a', 'c', 'd']
8
+
9
+ dog1 = {
10
+ :breed => "Husky/Lab Mix",
11
+ :name => "Rue",
12
+ :tricks => {
13
+ :not_jumping_up => false, # :( Workin on it!
14
+ :sitting => true,
15
+ :coming_when_called => true,
16
+ :other => [
17
+ {
18
+ :name => "trick1",
19
+ :value => false
20
+ },
21
+ {
22
+ :name => "trick2",
23
+ :value => true
24
+ }
25
+ ]
26
+ }
27
+ }
28
+
29
+ dog2 = dog1.dup
30
+ dog2[:tricks][:other].reverse!
31
+ dog1.must_have_same_content_as dog2
32
+ end
33
+
34
+ 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.2.1
4
+ version: 0.2.2
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-11-24 00:00:00.000000000 Z
12
+ date: 2012-11-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cancan
@@ -92,7 +92,7 @@ dependencies:
92
92
  - !ruby/object:Gem::Version
93
93
  version: '3.0'
94
94
  - !ruby/object:Gem::Dependency
95
- name: rails
95
+ name: minitest_tu_shim
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
@@ -108,7 +108,7 @@ dependencies:
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  - !ruby/object:Gem::Dependency
111
- name: debugger
111
+ name: rails
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  none: false
114
114
  requirements:
@@ -131,6 +131,7 @@ extensions: []
131
131
  extra_rdoc_files: []
132
132
  files:
133
133
  - .gitignore
134
+ - .travis.yml
134
135
  - Gemfile
135
136
  - LICENSE
136
137
  - README.md
@@ -140,16 +141,19 @@ files:
140
141
  - lib/cancan_strong_parameters/controller.rb
141
142
  - lib/cancan_strong_parameters/deep_permit.rb
142
143
  - lib/cancan_strong_parameters/rails/controller/base.rb
144
+ - lib/cancan_strong_parameters/ruby/hash.rb
143
145
  - lib/cancan_strong_parameters/version.rb
144
146
  - test/app/controllers/posts_controller.rb
145
147
  - test/app/controllers/title_controller.rb
146
148
  - test/app/models/post.rb
149
+ - test/assertions/assert_same_content.rb
147
150
  - test/config.ru
148
151
  - test/functional/posts_controller_test.rb
149
152
  - test/functional/title_controller_test.rb
150
153
  - test/rails_helper.rb
151
154
  - test/script/rails
152
155
  - test/test_helper.rb
156
+ - test/unit/assert_same_content_test.rb
153
157
  homepage: https://github.com/colinyoung/cancan_strong_parameters
154
158
  licenses: []
155
159
  post_install_message:
@@ -178,9 +182,11 @@ test_files:
178
182
  - test/app/controllers/posts_controller.rb
179
183
  - test/app/controllers/title_controller.rb
180
184
  - test/app/models/post.rb
185
+ - test/assertions/assert_same_content.rb
181
186
  - test/config.ru
182
187
  - test/functional/posts_controller_test.rb
183
188
  - test/functional/title_controller_test.rb
184
189
  - test/rails_helper.rb
185
190
  - test/script/rails
186
191
  - test/test_helper.rb
192
+ - test/unit/assert_same_content_test.rb