Conditional merge with Ruby to include a parameter if it hasn't been included
You want to merge params with one or more default values. How about, well, #merge?

{"published" =&gt; false}.merge(params[:template].permit!)


Only trick, if you can call it a trick, is that the default hash must use string keys, not symbols, despite the params object accepting either. The resulting hash will also be keyed with strings only.

Alternatively, you can use HashWithIndifferentAccess to get around this:

defaults = HashWithIndifferentAccess.new({ published: false })
filtered = defaults.merge(params[:template].permit!)


And filtered will be a HashWithIndifferentAccess much like params produces.

All that said, the better way to handle all this is to send the right parameters in the first place. With the code above you're always assuming that published should be set to false unless told otherwise. But there could be all sort of reasons for why only a subset of parameters are sent; if published is intentionally left out, it'll suddenly be filled in - perhaps wrongly - by the controller.

Relatedly, if the parameter is required, raise an exception if it's missing and tell the client. It's not the controller's job to fill in the blanks when faced with incomplete information. Conversely, it's the client's job to send the parameters that are necessary or required.

As I said in a comment, if you use Rails' regular checkbox helpers, they'll produce a hidden input with the checkbox's "unchecked" value, in addition to the checkbox input itself. If the checkbox is checked, it'll override the former, unchecked value. This is the typical (and better) way to solve this.

So in short, if you want to merge to hashes, use #merge. But in this case, you probably don't want to do that.