Jean
Jean

Reputation: 845

Rails strong parameters, user require and get an hash

I have this method

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

But now I want to check that all the keys are present. I tried to do this

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

But require return an array instead of an hash.

How can I do to have the same behaviour of permit but with require ?

Upvotes: 3

Views: 1923

Answers (2)

max
max

Reputation: 102203

require is only intended to ensure that the params have the correct general structure.

For example if you have:

params.require(:foo).permit(:bar, :baz)

require lets us bail early if the :foo key is missing since we cant do anything with the request.

require is not intended to validate the presence of individual params - that is handled with model level validations in Rails.

If you really had to you could do:

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

But thats just bad application design as you're letting the model level business logic creep into the controller.

Upvotes: 2

SteveTurczyn
SteveTurczyn

Reputation: 36860

permit and require are not interchangeable the way you think. If you establish that all the required keys are present, they still need to be permitted to be used in a mass assignment.

So you'd likely need to do...

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

The data.require will raise an ActionController::ParameterMissing exception if a key is missing, if not it will return the array of keys which can be used by permit.

Generally, what you want to do with require is more typically handled by model validation.

Documentation on require and permit is here...

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

Upvotes: 2

Related Questions