file_filedの注意点

今回、以下のformで画像をupすることにして、空で送ってしまったときはバリデーションにひっかかるように設定しようと思った。

<%= form_with(model: @user_icon, local: true) do |form| %>
  <%= form.file_field :image %>
  <%= form.submit "更新する" %>
<% end %>

しかし、これで送信すると、以下のようにparameterにrequire(:user_icon)のkeyがそもそもないため、コントローラーのstrong_paramsでエラーになってしまう。
user_icons_controller.rb

def create
    @user_icon = UserIcon.new(user_icon_params)
    if @user_icon.save
      redirect_to user_path(@user_icon.user_id), notice: 'アイコンを設定しました'
    else
      render 'users/show'
    end
  end
#省略
private
  def user_icon_params
    params.require(:user_icon).permit(:user_id, :image)
  end

エラー詳細

[2] pry(#<UserIconsController>)> params
=> <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"62WAR0vsxA+HqJabeXbmOOOCF7TfE+x9WLp0yXFOTes2+dFb8AHh0hq36kOsR7eH4zmbk8GvSjdqdAgvKwjnjA==", "commit"=>"更新する", "controller"=>"user_icons", "action"=>"create"} permitted: false>

とりあえずは、下記のようにform.file_fieldタグの他に、今回アソシエーションで紐づいて必要だったuser_idをhiddenタグをparameterに仕込むことで解決できた。

<%= form_with(model: @user_icon, local: true) do |form| %>
  <%= form.hidden_field :user_id, value: "#{current_user.id}" %>
  <%= form.file_field :image %>
  <%= form.submit "更新する" %>
<% end %>

ただ、今までnameやemailを全て空欄で送信してもバリデーションにひっかけることができたのに、なぜ今回はkey(この例では:user_icon)が設定されないのか不思議である。