如果从GUI传递数组/哈希,这与白名单参数有关。
以下是我想要的白名单。
注意:Orderplaced字段的类型为JSONB
private
def order_params
#params.require(:order).permit(:ordertype, :orderplaced => [:itemname => [], :quantity => [], :unitprice => [], :tax => [], :discount => [], :itemtotalprice => [] ])
params.require(:order).permit(:ordertype, :orderplaced => [ { itemname: [], quantity: [], unitprice: [], tax: [], discount: [], itemtotalprice: [] }])
#not working with either of the above statements.
end
end
服务器端错误未允许的参数
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).permit!
,那么我也只看到第一个值索引,即array [0]通过params传递并保存到DB。那我们怎样才能得到其余的。答案 0 :(得分:0)
您的代码存在许多问题。首先,您的白名单语法不正确。它应该更像是:
params.require(:order).permit(:ordertype, :totalprice, :paymentmethod, {orderplaced: {":itemname": ["0"], ":quantity": ["0"], ":unitprice": ["0"], ":tax": ["0"], ":discount": ["0"], ":itemtotalprice": ["0"]}})
在控制台中,这将为您提供:
> 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
值仍然使用密钥"0"
(例如":itemname"=>{"0"=>"Potatoe"}
)和orderplaced
个密钥在开头都有:
(例如":itemname"
)(由于您将orderplaced
存储在JSONB列中并且这是有效的JSON,您可以忽略这些问题。但是,现在清理它将为您或您的同事带来未来的心痛。)
您可以通过执行以下操作来解决此问题:
def orderplaced_params
order_params[:orderplaced].each_with_object({}) do |(k,v), returning|
returning[k.gsub(":","")] = v["0"]
end
end
再次在控制台中,它会给你:
> orderplaced_params
=> {"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}
现在,您需要重新组合固定的order_params。类似的东西:
def fixed_order_params
order_params.slice(:ordertype, :totalprice, :paymentmethod).merge!(orderplaced: orderplaced_params)
end
哪个会给你:
> fixed_order_params
=> {"ordertype"=>"Home Delivery", "totalprice"=>"30", "paymentmethod"=>"Cash", "orderplaced"=>{"itemname"=>"Potatoe", "quantity"=>"1", "unitprice"=>"10", "tax"=>"0", "discount"=>"0", "itemtotalprice"=>"10"}}
我有一种感觉,这不是故事的结局。根据你的用户界面(你还在发布图片!BOO!),我原本期望orderplaced
是一个哈希数组。类似的东西:
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"
}
(我假设您希望捕获图片中显示的每一行,作为orderplaced
JSONB列的一部分。)
在这种情况下,orderplaced_params需要看起来更像:
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
这会给你:
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_placed
而不是orderplaced
。order_placed
的哈希数组是正确的,那么你需要修复你的前端来传递数组而不是哈希。order_placed
不会在:
前加上discount
密钥(例如,:discount
,而不是order_placed
)。'discount'=>'0'
元素不会嵌入哈希值(例如,':discount'=>{'0'=>'0'}
,而不是order_placed_params
)最后两个会为您节省fixed_order_params
和order_params
所有商家的费用,并允许您返回仅使用NoMethodError (undefined method `each_with_object' for #<ActionController::Parameters:0xc17f808>):
。
关注
要避免:
ActionController::Parameters
尝试使用hash
to_h
转换为order_params[:orderplaced].to_h.each_with_object({}) do |(k,v), returning|
returning[k.gsub(":","")] = v["0"]
end
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import java.util.Arrays;
public class ClientUpdater extends Thread {
ClientCommunication cComm; //this is my class which manages the Server-Client-Communication
Intent BroadcastIntentUpdate; //Intent for the LocalBroadcast
Context cntxt; //stores the context passed in the constructor
GlobalClass Obj1; //Instance of my Singleton
public ClientUpdater(ClientCommunication cComm, Context context) {
this.cComm = cComm;
this.cntxt = context;
BroadcastIntentUpdate = new Intent("update");
}
public void run(){
while(true){
String vomS1 = cComm.sendData("updateChat" + "~" + "$empty$"); //sends an update request to the server an receives the current chat-state
if(!vomS1.equalsIgnoreCase("timeout")){
Obj1 = GlobalClass.getInstance();
String[] update = GlobalClass.decode(vomS1, ";"); //decodes the receives message
String[] altchat = Obj1.getChat(); //loads the stored chat protocoll from singleton
if(!Arrays.equals(update, altchat)){ //if the received message has new data...
BroadcastIntentUpdate.putExtra("message", update);
//for ".getInstance(cntxt)" the current Context is always needed right?
LocalBroadcastManager.getInstance(cntxt).sendBroadcast(BroadcastIntentUpdate); //...it's sent to the activity
Obj1.setChat(update); //...and stored in the singleton
}
}
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
答案 1 :(得分:0)
非常感谢您的回复。
在进行上述更改后(前端代码尚未修复),我看到一个问题未定义方法each_with_object' for #<ActionController::Parameters:0xc17f808>
in
orderplaced_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
服务器端错误:
Started POST "/orders" for 127.0.0.1 at 2018-01-04 19:21:44 +0530
Processing by OrdersController#create as HTML
Parameters: {"order"=>{"ordertype"=>"Home Deivery", "totalprice"=>"25", "paymentmethod"=>"Online", "orderplaced"=>{":quantity"=>{"0"=>"2"}, ":unitprice"=>{"0"=>"10"}, ":tax"=>{"0"=>"0"}, ":discount"=>{"0"=>"0"}, ":itemtotalprice"=>{"0"=>"20"}}}, "utf8"=>"Γ£ô", "authenticity_token"=>"e2RyLPkDVmCdxNgSzmK/Ov4dTJmCS1ZiM6G3T4u+8TflUd2UCOwnDU1/usslNQiZSGJdI3hNym14wehV9ClHfA==", "itemname"=>"Battery", "commit"=>"Create Order"}
Completed 500 Internal Server Error in 12ms (ActiveRecord: 0.0ms)
NoMethodError (undefined method `each_with_object' for #<ActionController::Parameters:0xc17f808>):
app/controllers/orders_controller.rb:25:in `orderplaced_params'
app/controllers/orders_controller.rb:31:in `fixed_order_params'
app/controllers/orders_controller.rb:10:in `create'
一行的前端代码:(通过增加索引值使用Java Script添加其余行)
<tr>
<td><input id="order[orderplaced][:itemname][0]" name="order[orderplaced][:itemname][0]" type="text" /></td>
<td><input id="order[orders_attributes][0][quantity]" name="order[orderplaced][:quantity][0]" type="text" /></td>
<td><input id="order[orders_attributes][0][unitprice]" name="order[orderplaced][:unitprice][0]" type="text" /></td>
<td><input id="order[orders_attributes][0][tax]" name="order[orderplaced][:tax][0]" type="text" /></td>
<td><input id="order[orders_attributes][0][discount]" name="order[orderplaced][:discount][0]" type="text" /></td>
<td><input id="order[orders_attributes][0][itemtotalprice]" name="order[orderplaced][:itemtotalprice][0]" type="text" /></td>
</tr>
你的猜测是正确的!我希望将orderplaced
存储在数据库中,以便我可以提取所需的Key及其值来显示。
哪种方式可以更容易地存储数据。
你出现的东西:
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"
}
或者这样
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"
}
答案 2 :(得分:0)
NoMethodError (undefined method
[]'为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