Rails 5.1 - JSON 参数是允许的,但在日志中仍显示为不允许
Rails 5.1 - JSON parameter is permitted but still prints as unpermitted in the log
在 Rails 4 here is the question 中关于如何做到这一点。我想知道的是,虽然这有效,但为什么日志仍然报错?
在 Rails 5.1.3 中,我有一个 JSON 列 (letterhead
) 作为我的模型属性之一(在 json 里面是一个散列与各种我不关心白名单的属性)。我只想 permit/whitelist 专栏本身。
Rails5.1.4
注意事项
在 5.1.4 中有一个 Rails 方法可以做到这一点,请参阅 this commit。
在 github 上对此进行了相当长的讨论 here。在 Rails 5.1.4 中就是这样:
def account_params
params.require(:account).permit(:id, :name, :plan_id, letterhead: {})
end
允许:letterhead
参数,日志中没有错误显示,模型保存。但显然它允许在该参数内任意输入,因此谨慎使用。
如果你确实想限制在这样的参数中允许使用哪些散列键,那么你也可以将它们列入白名单,例如:
def account_params
params.require(:account).permit(:id, :name, :plan_id, letterhead: [:address, :logo, :contact_info])
end
这现在可以防止 :letterhead
内的任何其他任意键,因为我明确只允许这 3 个 - :address, :logo, :contact_info
Rails 5.1.3(及更早版本)
我可以使用以下任一方法允许此专栏(也请参阅链接讨论以了解其他可能的选项):
选项 1
def account_params
params.require(:account).permit(:id, :name, :plan_id, :letterhead).tap do |whitelisted|
whitelisted[:letterhead] = params[:account].fetch(:letterhead, ActionController::Parameters.new).permit!
end
end
选项 2
def account_params
params.require(:account).permit(:id, :name, :plan_id, :letterhead).tap do |whitelisted|
whitelisted[:letterhead] = params[:account][:letterhead].permit!
end
end
在这两种情况下,模型都保存了,但在日志中它仍然显示 "unpermitted parameters :letterhead"
为什么明明允许了还这么说?
另外,方案一和方案二有什么区别吗?
编辑
数据是这样的:
{"id"=>"a61151b8-deed-4efa-8cad-da1b143196c9",
"plan_id"=>"1dc49acf-3111-4030-aea1-7db259b53a51",
"name"=>"Test Account 1",
"is_active"=>true,
"letterhead"=>{"left"=>"", "center"=>"", "right"=>""},
"created_by"=>nil,
"updated_by"=>nil,
"created_at"=>"2017-10-14T19:05:40.197Z",
"updated_at"=>"2017-10-20T15:14:08.194Z"}
为什么我已经明确允许了,还这么说?
日志来自#unpermitted_parameters!
which is called by #permit
。所有这一切都发生在 在 调用 #tap
.
之前
选项 1 和选项 2 之间有什么真正的区别吗?
区别归结为
params[:account].fetch(:letterhead, ActionController::Parameters.new).permit!
对
params[:account][:letterhead].permit!
如果 :letterhead
未通过,后者将导致 NoMethodError
,因为 params[:account][:letterhead]
将 return nil
。前者 return 是参数的空散列。
在 Rails 4 here is the question 中关于如何做到这一点。我想知道的是,虽然这有效,但为什么日志仍然报错?
在 Rails 5.1.3 中,我有一个 JSON 列 (letterhead
) 作为我的模型属性之一(在 json 里面是一个散列与各种我不关心白名单的属性)。我只想 permit/whitelist 专栏本身。
Rails5.1.4
注意事项在 5.1.4 中有一个 Rails 方法可以做到这一点,请参阅 this commit。 在 github 上对此进行了相当长的讨论 here。在 Rails 5.1.4 中就是这样:
def account_params
params.require(:account).permit(:id, :name, :plan_id, letterhead: {})
end
允许:letterhead
参数,日志中没有错误显示,模型保存。但显然它允许在该参数内任意输入,因此谨慎使用。
如果你确实想限制在这样的参数中允许使用哪些散列键,那么你也可以将它们列入白名单,例如:
def account_params
params.require(:account).permit(:id, :name, :plan_id, letterhead: [:address, :logo, :contact_info])
end
这现在可以防止 :letterhead
内的任何其他任意键,因为我明确只允许这 3 个 - :address, :logo, :contact_info
Rails 5.1.3(及更早版本)
我可以使用以下任一方法允许此专栏(也请参阅链接讨论以了解其他可能的选项):
选项 1
def account_params
params.require(:account).permit(:id, :name, :plan_id, :letterhead).tap do |whitelisted|
whitelisted[:letterhead] = params[:account].fetch(:letterhead, ActionController::Parameters.new).permit!
end
end
选项 2
def account_params
params.require(:account).permit(:id, :name, :plan_id, :letterhead).tap do |whitelisted|
whitelisted[:letterhead] = params[:account][:letterhead].permit!
end
end
在这两种情况下,模型都保存了,但在日志中它仍然显示 "unpermitted parameters :letterhead"
为什么明明允许了还这么说?
另外,方案一和方案二有什么区别吗?
编辑
数据是这样的:
{"id"=>"a61151b8-deed-4efa-8cad-da1b143196c9",
"plan_id"=>"1dc49acf-3111-4030-aea1-7db259b53a51",
"name"=>"Test Account 1",
"is_active"=>true,
"letterhead"=>{"left"=>"", "center"=>"", "right"=>""},
"created_by"=>nil,
"updated_by"=>nil,
"created_at"=>"2017-10-14T19:05:40.197Z",
"updated_at"=>"2017-10-20T15:14:08.194Z"}
为什么我已经明确允许了,还这么说?
日志来自#unpermitted_parameters!
which is called by #permit
。所有这一切都发生在 在 调用 #tap
.
选项 1 和选项 2 之间有什么真正的区别吗?
区别归结为
params[:account].fetch(:letterhead, ActionController::Parameters.new).permit!
对
params[:account][:letterhead].permit!
如果 :letterhead
未通过,后者将导致 NoMethodError
,因为 params[:account][:letterhead]
将 return nil
。前者 return 是参数的空散列。