Rails强大的参数,用户需要并获得哈希

时间:2017-03-28 08:59:31

标签: ruby-on-rails strong-parameters

我有这个方法

def create_billing_address(data)
    address_data = data.permit(:first_name,
                                :last_name,
                                :phone,
                                :address_1,
                                :city,
                                :postcode,
                                :country)
    service_customer.create_address(customer_id, address_data)
end

但现在我要检查所有键是否存在。我试着这样做

address_data = data.require(:first_name,
                            :last_name,
                            :phone,
                            :address_1,
                            :city,
                            :postcode,
                            :country)

但是要求返回一个数组而不是一个哈希。

如何使permitrequire具有相同的行为?

2 个答案:

答案 0 :(得分:2)

permitrequire不能像您想象的那样互换。如果您确定所有必需的密钥都存在,那么仍然需要被允许用于批量分配。

所以你可能需要做......

def create_billing_address(data)
  fields = %i(first_name last_name phone address_1 city postcode country)
  address_data = data.permit(data.require(fields))
  service_customer.create_address(customer_id, address_data)
end

如果缺少密钥,data.require将引发ActionController::ParameterMissing异常,否则会返回permit可以使用的密钥数组。

通常,您希望对require执行的操作通常由模型验证处理。

有关要求和许可的文件在这里......

http://api.rubyonrails.org/classes/ActionController/Parameters.html

答案 1 :(得分:1)

require仅用于确保参数具有正确的一般结构。

例如,如果你有:

params.require(:foo).permit(:bar, :baz)
如果require密钥丢失,

:foo可让我们提前保释,因为我们无法对请求做任何事情。

require无意验证单个参数的存在 - 这是通过Rails中的模型级验证来处理的。

如果你真的不得不这样做:

def create_billing_address!(data)
  keys = [:first_name, :last_name, :phone, :address_1, :city, :postcode, :country]

 keys.each do |k|
    raise ActionController::ParameterMissing and return unless data[k].present?
 end

 service_customer.create_address(customer_id, data.permit(*keys))
end

但那只是糟糕的应用程序设计,因为你让模型级别的业务逻辑蔓延到控制器中。