Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

First spike for `permit` with nested params

  • Loading branch information...
commit 12ebf52e6bc4c5cf137e0c267d627fff9ba60f5a 1 parent 5f79f9d
Piotr Sarnacki drogus authored
Showing with 114 additions and 2 deletions.
  1. +34 −2 lib/action_controller/parameters.rb
  2. +80 −0 test/nested_parameters_test.rb
36 lib/action_controller/parameters.rb
View
@@ -30,8 +30,32 @@ def required(key)
self[key].presence || raise(ActionController::ParameterMissing.new(key))
end
- def permit(*keys)
- slice(*keys).permit!
+ def permit(*filters)
+ params = self.class.new
+
+ filters.each do |filter|
+ case filter
+ when Symbol then
+ params[filter] = self[filter]
+ when Hash then
+ self.slice(*filter.keys).each do |key, value|
+ return unless value
+
+ key = key.to_sym
+
+ params[key] = each_element(value) do |value|
+ # filters are a Hash, so we expect value to be a Hash too
+ next if filter.is_a?(Hash) && !value.is_a?(Hash)
+
+ value = self.class.new(value) if !value.respond_to?(:permit)
+
+ value.permit(*Array.wrap(filter[key]))
+ end
+ end
+ end
+ end
+
+ params.permit!
end
def [](key)
@@ -59,6 +83,14 @@ def convert_hashes_to_parameters(key, value)
self[key] = self.class.new(value)
end
end
+
+ def each_element(object)
+ if object.is_a?(Array)
+ object.map { |el| yield el }.compact
+ else
+ yield object
+ end
+ end
end
module StrongParameters
80 test/nested_parameters_test.rb
View
@@ -0,0 +1,80 @@
+require 'test_helper'
+require 'action_controller/parameters'
+
+class NestedParametersTest < ActiveSupport::TestCase
+ test "permitted nested parameters" do
+ params = ActionController::Parameters.new({
+ book: {
+ title: "Romeo and Juliet",
+ authors: [{
+ name: "William Shakespeare",
+ born: "1564-04-26"
+ }, {
+ name: "Christopher Marlowe"
+ }],
+ details: {
+ pages: 200,
+ genre: "Tragedy"
+ }
+ },
+ magazine: "Mjallo!"
+ })
+
+ permitted = params.permit book: [ :title, { authors: [ :name ] }, { details: :pages } ]
+
+ assert permitted.permitted?
+ assert_equal "Romeo and Juliet", permitted[:book][:title]
+ assert_equal "William Shakespeare", permitted[:book][:authors][0][:name]
+ assert_equal "Christopher Marlowe", permitted[:book][:authors][1][:name]
+ assert_equal 200, permitted[:book][:details][:pages]
+ assert_nil permitted[:book][:details][:genre]
+ assert_nil permitted[:book][:authors][1][:born]
+ assert_nil permitted[:magazine]
+ end
+
+ test "nested arrays with strings" do
+ params = ActionController::Parameters.new({
+ book: {
+ genres: ["Tragedy"]
+ }
+ })
+
+ permitted = params.permit book: :genres
+ assert_equal ["Tragedy"], permitted[:book][:genres]
+ end
+
+ test "nested array with strings that should be hashes" do
+ params = ActionController::Parameters.new({
+ book: {
+ genres: ["Tragedy"]
+ }
+ })
+
+ permitted = params.permit book: { genres: :type }
+ assert_empty permitted[:book][:genres]
+ end
+
+ test "nested array with strings that should be hashes and additional values" do
+ params = ActionController::Parameters.new({
+ book: {
+ title: "Romeo and Juliet",
+ genres: ["Tragedy"]
+ }
+ })
+
+ permitted = params.permit book: [ :title, { genres: :type } ]
+ assert_equal "Romeo and Juliet", permitted[:book][:title]
+ assert_empty permitted[:book][:genres]
+ end
+
+ test "nested string that should be a hash" do
+ params = ActionController::Parameters.new({
+ book: {
+ genre: "Tragedy"
+ }
+ })
+
+ permitted = params.permit book: { genre: :type }
+ assert_nil permitted[:book][:genre]
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.