John Smith
John Smith

Reputation: 6259

Add params in strong parameters

Lets say I have params like this:

def boat_params
   params
      .require(:boat)
      .permit(:message
              :alarm_en,
              :alarm_es,
              :alarm_sv)
end

What I try is basically shorten this code, with:

def boat_params
   params
      .require(:boat)
      .permit(:message).merge(alarm_params)
end

But for alarm_params I get errors when I tried:

def alarm_params
    params = {}
    ["en","es","sv"].each do |lang|
       params << "alarm_#{lang}" 
    end
    return params
end

What raised the error:

undefined method `<<' for {}:Hash

for: params << "alarm_#{lang}"


Next I tried it with an Array:

def alarm_params
    params = []
    ["en","es","sv"].each do |lang|
       params << "alarm_#{lang}" 
    end
    return params
end

What raised the error:

 undefined method `to_hash' 

In .merge(alarm_params)

What do I wrong? Thanks!

Upvotes: 1

Views: 1175

Answers (2)

coreyward
coreyward

Reputation: 80041

You're calling merge on the result of permit, which returns ActionController::Parameters, not a generic hash.

Since permit takes an array, you can actually just do the following:

def alarm_params
  %w{ alarm_en alarm_es alarm_sv }
end

def boat_params
  params.require(:boat).permit(:message, *alarm_params)
end

If you wanted to use metaprogramming to pull a list of languages and create the permitted params for each, as you're currently doing in alarm_params, you could do the following more readily:

def languages
  # possibly use a more global config var, or ENV
  # e.g. ENV['SUPPORTED_LANGUAGES']
  %w{ en es sv }
end

def alarm_params
  languages.map { |lang| "alarm_#{lang}" }
end

No need for each, or the explicit return.

Upvotes: 1

Danny Ocean
Danny Ocean

Reputation: 1111

The argument to the permit is an array, not a hash. You can try to use the splat operator *

def boat_params
   params
      .require(:boat)
      .permit(:message, *alarm_params)
end

Upvotes: 1

Related Questions