2017-10-20 48 views
6

在Rails 4 here is the question有关如何做到这一点英寸我想知道的是,虽然这是有效的,但为什么日志仍然在抱怨?的Rails 5.1 - JSON参数是允许的,但仍作为打印未经许可的日志

在Rails 5.1.3中,我有一个JSON列(letterhead)作为我的一个模型属性(并且里面的那个json是一个包含各种属性的散列,我不关心白名单)。我只是想允许/列入白名单本身。

注on Rails的5.1.4

有一个Rails的方式做到这一点在5.1.4,看到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 

在这两种情况下,模型都会保存,但在日志中仍然会显示“未经许可的参数:信头”

  1. 为什么仍然说,当我已经明确允许的吗?

  2. 此外,有没有选项1和选项2之间的任何真实的差异?

编辑

的数据是这样的:

{"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"} 
+0

如何让传入的数据看起来像? – 7urkm3n

+0

@ 7urkm3n我添加了一个显示数据的编辑 – rmcsharry

+0

你看到了什么样的错误(抱怨)?你可以发表年度日志和使用方法吗? – 7urkm3n

回答

1

为什么仍然说,当我已经明确允许的吗?

日志来自#unpermitted_parameters!这是由#permit调用。所有这一切发生在之前呼叫#tap

选项1和选项2之间是否有实际区别?

的差异归结为

params[:account].fetch(:letterhead, ActionController::Parameters.new).permit! 

VS

params[:account][:letterhead].permit! 

后者将导致NoMethodError如果:letterhead没有通过,因为params[:account][:letterhead]将返回nil。前者返回参数的空哈希值。

+0

谢谢你对这两个问题的全面回答。但最后一段没有意义。你说后者会导致NoMethodError ...将返回零。它不能同时返回?还有最后一句完成 - 它以方括号结束? – rmcsharry

+1

@rmcsharry,最后一段是由于我的Kinesis类型;-)我想到的是'#[]'和'#fetch'之间的区别。如果':letterhead'没有通过,那么'params [:account] [:letterhead]'是'nil','nil'不会定义'#permit!'。 –

+0

我现在看到了,谢谢澄清。你应得的奖金:) – rmcsharry