Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #286 from prijutme4ty/strong_params

strong parameter support refined to allow standard Rails 4 notation
  • Loading branch information...
commit 1e186175465c55b233b0452e4c72c5856becfbbc 2 parents 5b61f8a + d1ad934
@joelmoss joelmoss authored
View
4 Gemfile
@@ -5,3 +5,7 @@ gemspec
gem 'rails', '>= 3.2', '< 5'
gem 'mocha'
gem 'turn'
+
+group :test do
+ gem 'strong_parameters'
+end
View
5 Gemfile.lock
@@ -80,6 +80,10 @@ GEM
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (~> 2.8)
+ strong_parameters (0.1.4)
+ actionpack (>= 3.2.0)
+ activemodel (>= 3.2.0)
+ railties (>= 3.2.0)
thor (0.18.1)
thread_safe (0.1.2)
atomic
@@ -98,4 +102,5 @@ DEPENDENCIES
inherited_resources!
mocha
rails (>= 3.2, < 5)
+ strong_parameters
turn
View
10 README.md
@@ -706,6 +706,16 @@ def build_resource_params
end
```
+
+Instead you can stick to a standard Rails 4 notation (as rails scaffold generates) and write:
+
+ def widget_params
+ params.require(:widget).permit(:permitted_field, :other_permitted_field)
+ end
+
+In such case you should remove #permitted_params method because it has greater priority.
+
+
## Bugs and Feedback
If you discover any bugs, please describe it in the issues tracker, including Rails and InheritedResources versions.
View
37 lib/inherited_resources/base_helpers.rb
@@ -316,9 +316,44 @@ def resource_params
@resource_params ||= build_resource_params
end
+ def resource_params_method_name
+ "#{resource_instance_name}_params"
+ end
+
+ # Returns hash of sanitized params in a form like
+ # `{:project => {:project_attribute => 'value'}}`
+ #
+ # This method makes use of `project_params` (or `smth_else_params`) which
+ # is a default Rails controller method for strong parameters definition.
+ #
+ # `permitted_params` is usually fired by method :new, :create, :update
+ # actions. Action :new usually has no parameters so strong parameters
+ # `require` directive raises a +ActionController::ParameterMissing+
+ # exception. `#permitted_params` rescues such exceptions in :new and
+ # returns an empty hash of parameters (which is reasonable default).
+ # If for any reasons you need something more specific, you can redefine
+ # this method in a way previous `inherited_resources` versions did:
+ #
+ # # Unnecessary redefinition
+ # def permitted_params
+ # params.permit(:project => [:project_attribute])
+ # end
+ #
+ def permitted_params
+ return nil unless respond_to?(resource_params_method_name, true)
+ {resource_request_name => send(resource_params_method_name)}
+ rescue ActionController::ParameterMissing
+ # typically :new action
+ if params[:action].to_s == 'new'
+ {resource_request_name => {}}
+ else
+ raise
+ end
+ end
+
# extract attributes from params
def build_resource_params
- parameters = respond_to?(:permitted_params, true) ? permitted_params : params
+ parameters = permitted_params || params
rparams = [parameters[resource_request_name] || parameters[resource_instance_name] || {}]
if without_protection_given?
rparams << without_protection
View
85 test/strong_parameters_test.rb
@@ -1,5 +1,9 @@
require File.expand_path('test_helper', File.dirname(__FILE__))
+if ActionPack::VERSION::MAJOR == 3
+ require 'strong_parameters'
+end
+
class Widget
extend ActiveModel::Naming
end
@@ -7,6 +11,7 @@ class Widget
class WidgetsController < InheritedResources::Base
end
+# test usage of `permitted_params`
class StrongParametersTest < ActionController::TestCase
def setup
@controller = WidgetsController.new
@@ -34,4 +39,82 @@ def test_permitted_params_from_update
Widget.expects(:find).with('42').returns(mock_widget)
put :update, :id => '42', :widget => {:permitted => 'param', :prohibited => 'param'}
end
-end
+
+ # `permitted_params` has greater priority than `widget_params`
+ def test_with_permitted_and_resource_methods
+ @controller.stubs(:widget_params).returns(:permitted => 'another_param')
+ class << @controller
+ private :widget_params
+ end
+ Widget.expects(:new).with(:permitted => 'param')
+ get :new, :widget => { :permitted => 'param', :prohibited => 'param' }
+ end
+end
+
+# test usage of `widget_params`
+class StrongParametersWithoutPermittedParamsTest < ActionController::TestCase
+ def setup
+ @controller = WidgetsController.new
+ @controller.stubs(:widget_url).returns("/")
+ @controller.stubs(:widget_params).returns(:permitted => 'param')
+ class << @controller
+ private :widget_params
+ end
+ end
+
+ def test_permitted_params_from_new
+ Widget.expects(:new).with(:permitted => 'param')
+ get :new, :widget => { :permitted => 'param', :prohibited => 'param' }
+ end
+
+ def test_permitted_params_from_create
+ Widget.expects(:new).with(:permitted => 'param').returns(mock(:save => true))
+ post :create, :widget => { :permitted => 'param', :prohibited => 'param' }
+ end
+
+ def test_permitted_params_from_update
+ mock_widget = mock
+ mock_widget.stubs(:class).returns(Widget)
+ mock_widget.expects(:update_attributes).with(:permitted => 'param')
+ Widget.expects(:find).with('42').returns(mock_widget)
+ put :update, :id => '42', :widget => {:permitted => 'param', :prohibited => 'param'}
+ end
+end
+
+# test usage of `widget_params` integrated with strong parameters (not using stubs)
+class StrongParametersIntegrationTest < ActionController::TestCase
+ def setup
+ @controller = WidgetsController.new
+ @controller.stubs(:widget_url).returns("/")
+
+ class << @controller
+ define_method :widget_params do
+ params.require(:widget).permit(:permitted)
+ end
+ private :widget_params
+ end
+ end
+
+ def test_permitted_empty_params_from_new
+ Widget.expects(:new).with({})
+ get :new, {}
+ end
+
+ def test_permitted_params_from_new
+ Widget.expects(:new).with('permitted' => 'param')
+ get :new, :widget => { :permitted => 'param', :prohibited => 'param' }
+ end
+
+ def test_permitted_params_from_create
+ Widget.expects(:new).with('permitted' => 'param').returns(mock(:save => true))
+ post :create, :widget => { :permitted => 'param', :prohibited => 'param' }
+ end
+
+ def test_permitted_params_from_update
+ mock_widget = mock
+ mock_widget.stubs(:class).returns(Widget)
+ mock_widget.expects(:update_attributes).with('permitted' => 'param')
+ Widget.expects(:find).with('42').returns(mock_widget)
+ put :update, :id => '42', :widget => {:permitted => 'param', :prohibited => 'param'}
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.