Rails 4 Strong Parameters - Handling Missing Model Params Hash

Benjamin picture Benjamin · Jun 28, 2013 · Viewed 13.1k times · Source

Models: Posts and Users

Post belongs_to :user
User has_many :posts

Simple.

Assuming a few users exist, we visit the edit page for a Post.

<%= form_for @post do |f| %>

...

<% User.all.each do |user| %>
  <div><%= f.radio_button "user_id", user.id %></div>
<% end %>

...

The Post's Controller leverages Rails 4 strong parameters.

params.require(:post).permit(:user_id)

Assume the edit post form only has the radio buttons as fields.

Problem: ActionController::ParameterMissing exception is thrown. param not found: post

The reason being the Post params hash is never created, causing the above exception to be thrown. Empty radio buttons, unlike empty text fields for example, do not trigger the model's param hash to be created.

What if the Post model requires a user_id to be valid? Certainly one would want to render the view again with the reason why the Post can't be saved.

Question: What is an elegant way to handle this situation while sticking to Rails convention?

UPDATE:

Brainstorming about this further, I'm sure there are probably plenty of other situations which generate this problem; it does not necessarily correspond to radio buttons.

Answer

PaulL picture PaulL · Mar 17, 2014

I have a similar problem, and didn't like either of these answers much. In the rails documentation (http://guides.rubyonrails.org/action_controller_overview.html#more-examples) I see the following solution:

params.fetch(:blog, {}).permit(:title, :author)

Effectively you are supplying a default of {}, which seems to work well enough (at least for my situation).

Applying to your code, you'd have:

params.fetch(:post, {}).permit(:user_id)

I think this is reasonably clean, and seems to work in my code.