ruby-on-railscontrollerform-for

Unpermitted parameters utf8, method in update action


This one is driving me crazy...

I have a form_for for which I want to update a campaign record.

I'm getting the following error in logs when submitting the form and updating a campaign:

Unpermitted parameters: :utf8, :_method, :authenticity_token, :campaign, :commit

Campaign params

def campaign_params
  params.permit(:box, :id, :name, :photo1, :delivery_date, :numberofitems, :extras, :card, :custom_message, :shipping_type, :totalitems, :companylogodesign, :companycarddesign,:selectedproducts => [])
end

My routes:

resources :campaigns

My form:

<%= form_with(model: campaign, local: true) do |form| %>
  <% if campaign.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(campaign.errors.count, "error") %> prohibited this campaign from being saved:</h2>

      <ul>
      <% campaign.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :name %>
    <%= form.text_field :name %>
  </div>

  <div class="field">
    <%= form.label :status %>
    <%= form.number_field :status %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

In my controller action, I have the most simple update method:

  def update
    respond_to do |format|
      if @campaign.update(campaign_params)
        format.html { redirect_to @campaign, notice: 'Campaign was successfully updated.' }
        format.json { render :show, status: :ok, location: @campaign }
      else
        format.html { render :edit }
        format.json { render json: @campaign.errors, status: :unprocessable_entity }
      end
    end
  end

Error Logs:

Started PATCH "/campaigns/8" for ::1 at 2021-03-31 01:02:25 +0200
Processing by CampaignsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"6/k7vBdzh/PxeGFnzVcny2w23Tm1XUd2BnIB1X0l56fDQA1Psudlb3uKzp983ER4RUdJMayeRD88wANRl1k6GA==", "campaign"=>{"name"=>"sdsd", "status"=>""}, "commit"=>"Update Campaign", "id"=>"8"}
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ /Users/x/.rvm/gems/ruby-2.7.2/gems/activerecord-5.2.4.4/lib/active_record/log_subscriber.rb:98
  Campaign Load (0.2ms)  SELECT  "campaigns".* FROM "campaigns" WHERE "campaigns"."id" = $1 LIMIT $2  [["id", 8], ["LIMIT", 1]]
  ↳ app/controllers/campaigns_controller.rb:93
Unpermitted parameters: :utf8, :_method, :authenticity_token, :campaign, :commit

¿What am I missing? Thanks a lot in advance


Solution

  • I think that what you are trying to achieve is something like:

    if @campaign.update(campaign_params.require(:campaign).permit!)
    

    But permit! is pretty risk. So I'd go with this:

    if @campaign.update(campaign_params.require(:campaign).permit(:name, :status))
    

    Explanation

    See... When you declare a model/scope to your form, Rails will nest this parameters with the model/scope name.

    So the parameters you are using inside the form are nested under the campaign key. By default, Rails will send some extra params, as you may have already noticed (authenticity_token,commit, utf8, etc...).

    The unpermitted params error mean that you cannot use these params to update an entity (for security reasons) unless you explicitly declare it.