Ruby on rails 将Rails 5中的参数列入白名单

Ruby on rails 将Rails 5中的参数列入白名单,ruby-on-rails,postgresql,jsonb,Ruby On Rails,Postgresql,Jsonb,如果从GUI传递数组/哈希,则这与白名单参数有关 下面是我试图将其列入白名单的内容 但在服务器端看到一个错误,表示未经允许的参数 注意:Orderplaced字段的类型为JSONB 服务器端错误未允许的参数 Started POST "/orders" for 127.0.0.1 at 2018-01-03 20:00:23 +0530 Processing by OrdersController#create as HTML Parameters: {"order"=>{"ord

如果从GUI传递数组/哈希,则这与白名单参数有关

下面是我试图将其列入白名单的内容

  • 但在服务器端看到一个错误,表示未经允许的参数
  • 注意:Orderplaced字段的类型为JSONB



    服务器端错误未允许的参数

    Started POST "/orders" for 127.0.0.1 at 2018-01-03 20:00:23 +0530
    Processing by OrdersController#create as HTML
      Parameters: {"order"=>{"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>{":itemname"=>{"0"=>"Potatoe"}, ":quantity"=>{"0"=>"1"}, ":unitprice"=>{"0"=>"10"}, ":tax"=>{"0"=>"0"}, ":discount"=>{"0"=>"0"}, ":itemtotalprice"=>{"0"=>"10"}}}, "utf8"=>"Γ£ô", "authenticity_token"=>"1etU+M03uuTl8wcGij1+qEaSFcp/UvgBu3g/xBh0Hmexm4rA1vtCc1mkIWFsw8XcfC2sz2e9TBSmSBZNA9KiNA==", "commit"=>"Create Order"}
    Unpermitted parameters: ::itemname, ::quantity, ::unitprice, ::tax, ::discount, ::itemtotalprice
      Customer Load (0.0ms)  SELECT  "customers".* FROM "customers" ORDER BY "customers"."id" ASC LIMIT $1  [["LIMIT", 1]]
       (0.0ms)  BEGIN
      SQL (4.0ms)  INSERT INTO "orders" ("ordertype", "orderplaced", "totalprice", "paymentmethod", "created_at", "updated_at", "customer_id") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"  [["ordertype", "Home Delivery"], ["orderplaced", "{}"], ["totalprice", 30.0], ["paymentmethod", "Cash"], ["created_at", "2018-01-03 14:30:23.393041"], ["updated_at", "2018-01-03 14:30:23.393041"], ["customer_id", 1]]
       (8.0ms)  COMMIT
    

  • 如果我使用
    params.require(:order)。允许然后我只看到值的第一个索引,即数组[0]通过参数传递并保存到DB。那我们怎么才能得到剩下的呢
  • 图形用户界面:
    您的代码有很多问题。首先,您的白名单语法不正确。它应该更像:

    params.require(:order).permit(:ordertype, :totalprice, :paymentmethod, {orderplaced: {":itemname": ["0"], ":quantity": ["0"], ":unitprice": ["0"], ":tax": ["0"], ":discount": ["0"], ":itemtotalprice": ["0"]}})
    
    def orderplaced_params
      order_params[:orderplaced].map do |order_line_item|
        order_line_item.each_with_object({}) do |(k,v), hsh|
          hsh[k.gsub(":","")] = v["0"]
        end
      end
    end
    
    在控制台中,这将为您提供:

    > params.require(:order).permit(:ordertype, :totalprice, :paymentmethod, {orderplaced: {":itemname": ["0"], ":quantity": ["0"], ":unitprice": ["0"], ":tax": ["0"], ":discount": ["0"], ":itemtotalprice": ["0"]}})
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>{":itemname"=>{"0"=>"Potatoe"}, ":quantity"=>{"0"=>"1"}, ":unitprice"=>{"0"=>"10"}, ":tax"=>{"0"=>"0"}, ":discount"=>{"0"=>"0"}, ":itemtotalprice"=>{"0"=>"10"}}}
    
    > orderplaced_params
     => {"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}
    
    > fixed_order_params
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>{"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}}
    
    fixed_order_params
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>[{"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}, {"itemname"=>"Television", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}, {"itemname"=>"Cable", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}]} 
    
    这仍然有两个问题:

  • 您的
    orderplacted
    值仍然嵌入在散列中,所有散列都带有键
    “0”
    (例如,
    “:itemname”=>{“0”=>“Potatoe”}
    ),并且
  • 您的
    orderplacted
    键的开头都有一个
    (例如,
    “:itemname”
  • (由于您正在JSONB列中存储
    orderplaced
    ,并且这是有效的JSON,因此您可以忽略这些问题。但是,现在将其清除将避免将来您或您的同事的心痛。)

    您可以通过执行以下操作来解决此问题:

    def orderplaced_params
      order_params[:orderplaced].each_with_object({}) do |(k,v), returning|
        returning[k.gsub(":","")] = v["0"]
      end
    end
    
    def fixed_order_params
      order_params.slice(:ordertype, :totalprice, :paymentmethod).merge!(orderplaced: orderplaced_params)
    end
    
    同样在控制台中,它将为您提供:

    > params.require(:order).permit(:ordertype, :totalprice, :paymentmethod, {orderplaced: {":itemname": ["0"], ":quantity": ["0"], ":unitprice": ["0"], ":tax": ["0"], ":discount": ["0"], ":itemtotalprice": ["0"]}})
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>{":itemname"=>{"0"=>"Potatoe"}, ":quantity"=>{"0"=>"1"}, ":unitprice"=>{"0"=>"10"}, ":tax"=>{"0"=>"0"}, ":discount"=>{"0"=>"0"}, ":itemtotalprice"=>{"0"=>"10"}}}
    
    > orderplaced_params
     => {"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}
    
    > fixed_order_params
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>{"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}}
    
    fixed_order_params
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>[{"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}, {"itemname"=>"Television", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}, {"itemname"=>"Cable", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}]} 
    
    现在,您需要重新组装您的固定顺序参数。比如:

    def orderplaced_params
      order_params[:orderplaced].each_with_object({}) do |(k,v), returning|
        returning[k.gsub(":","")] = v["0"]
      end
    end
    
    def fixed_order_params
      order_params.slice(:ordertype, :totalprice, :paymentmethod).merge!(orderplaced: orderplaced_params)
    end
    
    这将给你:

    > params.require(:order).permit(:ordertype, :totalprice, :paymentmethod, {orderplaced: {":itemname": ["0"], ":quantity": ["0"], ":unitprice": ["0"], ":tax": ["0"], ":discount": ["0"], ":itemtotalprice": ["0"]}})
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>{":itemname"=>{"0"=>"Potatoe"}, ":quantity"=>{"0"=>"1"}, ":unitprice"=>{"0"=>"10"}, ":tax"=>{"0"=>"0"}, ":discount"=>{"0"=>"0"}, ":itemtotalprice"=>{"0"=>"10"}}}
    
    > orderplaced_params
     => {"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}
    
    > fixed_order_params
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>{"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}}
    
    fixed_order_params
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>[{"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}, {"itemname"=>"Television", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}, {"itemname"=>"Cable", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}]} 
    
    我觉得这还不是故事的结局。基于您的UI(您仍然在发布图片!BOO!),我本以为
    orderplacted
    是一个散列数组。比如:

    Parameters: {
      "order"=>{
        "ordertype"=>"Home Delivery", 
        "totalprice"=>"30", 
        "paymentmethod"=>"Cash", 
        "orderplaced"=>[
          {
            ":itemname"=>{"0"=>"Potatoe"}, 
            ":quantity"=>{"0"=>"1"}, 
            ":unitprice"=>{"0"=>"10"}, 
            ":tax"=>{"0"=>"0"}, 
            ":discount"=>{"0"=>"0"}, 
            ":itemtotalprice"=>{"0"=>"10"}
          },
          {
            ":itemname"=>{"0"=>"Television"}, 
            ":quantity"=>{"0"=>"1"}, 
            ":unitprice"=>{"0"=>"10"}, 
            ":tax"=>{"0"=>"0"}, 
            ":discount"=>{"0"=>"0"}, 
            ":itemtotalprice"=>{"0"=>"10"}
          },
          {
            ":itemname"=>{"0"=>"Cable"}, 
            ":quantity"=>{"0"=>"1"}, 
            ":unitprice"=>{"0"=>"10"}, 
            ":tax"=>{"0"=>"0"}, 
            ":discount"=>{"0"=>"0"}, 
            ":itemtotalprice"=>{"0"=>"10"}
          }
        ]
      }, 
      "utf8"=>"Γ£ô", 
      "authenticity_token"=>"1etU+M03uuTl8wcGij1+qEaSFcp/UvgBu3g/xBh0Hmexm4rA1vtCc1mkIWFsw8XcfC2sz2e9TBSmSBZNA9KiNA==",
      "commit"=>"Create Order"
    }
    
    (我假设您希望捕获图片中显示的每一行,作为
    orderplacted
    JSONB列的一部分。)

    在这种情况下,orderplaced_参数需要看起来更像:

    params.require(:order).permit(:ordertype, :totalprice, :paymentmethod, {orderplaced: {":itemname": ["0"], ":quantity": ["0"], ":unitprice": ["0"], ":tax": ["0"], ":discount": ["0"], ":itemtotalprice": ["0"]}})
    
    def orderplaced_params
      order_params[:orderplaced].map do |order_line_item|
        order_line_item.each_with_object({}) do |(k,v), hsh|
          hsh[k.gsub(":","")] = v["0"]
        end
      end
    end
    
    这将给你:

    > params.require(:order).permit(:ordertype, :totalprice, :paymentmethod, {orderplaced: {":itemname": ["0"], ":quantity": ["0"], ":unitprice": ["0"], ":tax": ["0"], ":discount": ["0"], ":itemtotalprice": ["0"]}})
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>{":itemname"=>{"0"=>"Potatoe"}, ":quantity"=>{"0"=>"1"}, ":unitprice"=>{"0"=>"10"}, ":tax"=>{"0"=>"0"}, ":discount"=>{"0"=>"0"}, ":itemtotalprice"=>{"0"=>"10"}}}
    
    > orderplaced_params
     => {"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}
    
    > fixed_order_params
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>{"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}}
    
    fixed_order_params
     => {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>[{"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}, {"itemname"=>"Television", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}, {"itemname"=>"Cable", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}]} 
    
    需要注意的几点:

    • 这是“土豆”,不是“土豆”
    • 您应该研究格式化代码的方法。变量通常带有下划线,例如:
      order\u-placed
      而不是
      orderplaced
    • 如果我对
      order\u placed
      的哈希数组的看法正确,那么您需要修复前端以传递数组,而不仅仅是哈希
    • 您应该修复前端,使您下的
      订单
      键不受
      的影响(例如,
      折扣
      ,而不是
      :折扣
    • 您应该修复前端,以便放置的
      订单
      元素不会嵌入哈希中(例如,
      'discount'=>'0'
      ,而不是
      ':discount'=>{'0'=>'0'}
    最后两个将为您节省所有
    order\u-placed\u-params
    fixed\u-order\u-params
    业务,并允许您重新使用
    order\u-params

    跟进

    为了避免:

    NoMethodError (undefined method `each_with_object' for #<ActionController::Parameters:0xc17f808>):
    

    非常感谢您的回复

    在进行了上述更改(前端代码尚未修复)之后,我看到了一个问题:未定义方法
    each_with_object'for#
    在
    orderplacted_params`方法中


    控制器代码:

    class OrdersController < ApplicationController
    
        def new
            @order=Order.new
        end
    
        def create
            @order=Order.new(fixed_order_params)
            @order.save
        end
    
        private
            def order_params
                params.require(:order).permit(:ordertype, :totalprice, :paymentmethod, {orderplaced: {":itemname": ["0"], ":quantity": ["0"], ":unitprice": ["0"], ":tax": ["0"], ":discount": ["0"], ":itemtotalprice": ["0"]}})
            end
    
    
            def orderplaced_params
                order_params[:orderplaced].each_with_object({}) do |(k,v), returning|
                returning[k.gsub(":","")] = v["0"]
                 end
            end
    
            def fixed_order_params
                order_params.slice(:ordertype, :totalprice, :paymentmethod).merge!(orderplaced: orderplaced_params)
            end
    
        end
    
    还是这样

    Parameters: {
      "order"=>{
        "ordertype"=>"Home Delivery", 
        "totalprice"=>"30", 
        "paymentmethod"=>"Cash", 
        "orderplaced"=>[
          {
            ":itemname"=>{"0"=>"Potatoe","1"=>"Television","2"=>"Cable"}, 
            ":quantity"=>{"0"=>"1","1"=>"1","2"=>"1"}, 
            ":unitprice"=>{"0"=>"10","1"=>"10","2"=>"10"}, 
            ":tax"=>{"0"=>"0","1"=>"0","2"=>"0"}, 
            ":discount"=>{"0"=>"0","1"=>"0","2"=>"0"}, 
            ":itemtotalprice"=>{"0"=>"10","1"=>"10","2"=>"10"}
          }
        ]
      }, 
      "utf8"=>"Γ£ô", 
      "authenticity_token"=>"1etU+M03uuTl8wcGij1+qEaSFcp/UvgBu3g/xBh0Hmexm4rA1vtCc1mkIWFsw8XcfC2sz2e9TBSmSBZNA9KiNA==",
      "commit"=>"Create Order"
    }
    

    命名方法错误(对于nil:NilClass,未定义的方法)`

    作为一个初学者,我很难理解发生了什么

    我知道这是一个数组问题。但我不确定我错在哪里

    def orderplaced_params
              order_params[:orderplaced].to_h.map do |order_line_item|
                order_line_item.each_with_object({}) do |(k,v), hsh|
                  hsh[k.gsub(":","")] = v["0"]
                end
              end
            end
    

    请不要拍照。它们不仅难以阅读,而且无法突出显示可能的错误/问题。我知道如何单击链接。重点是,你不应该包括图像的原因,我说。您应该复制控制台输出并将其粘贴到问题中(格式为代码)。@AbdulMuqeem关键是您应该发布文本,而不是图像。当然可以@jvillian。我也会这么做。很抱歉给您带来不便。这些是静止图像。我会解决你的问题,但我不能剪切和粘贴你的参数。我想太糟糕了。谢谢你。成功了。但是在orderplaced_params上卡住了。@jvilian,你能帮我整理一下这个问题吗。