JustinBull
JustinBull

Reputation: 226

Strong Parameters claims param not found when it's present

So for some reason I'm getting the ActionController::ParameterMissing error. It says incident parameter is missing however it's clearly present:

Started PATCH "/incidents/16/assign-score" for 127.0.0.1 at 2013-11-23 23:07:12 -0500
Processing by IncidentsController#update_override_score as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"RSGaHrrTrO5DoX8dVEtVNQX8OJnRAD35YRSCAvZtNr4=", "incident"=>{"id"=>"16", "score_override"=>"5"}, "commit"=>"Save legitimacy score", "id"=>"16"}
Unpermitted parameters: id, score_override
  Incident Load (0.1ms)  SELECT "incidents".* FROM "incidents" WHERE "incidents"."id" = ? LIMIT 1  [["id", "16"]]
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
  CACHE (0.0ms)  SELECT "incidents".* FROM "incidents" WHERE "incidents"."id" = ? LIMIT 1  [["id", "16"]]
Completed 400 Bad Request in 9ms

ActionController::ParameterMissing (param not found: incident):
  app/controllers/incidents_controller.rb:66:in `update_override_score'


  Rendered /Users/justinbull/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.6ms)
  Rendered /Users/justinbull/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.0ms)
  Rendered /Users/justinbull/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.0ms)
  Rendered /Users/justinbull/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (62.8ms)

Relevant controller code:

class IncidentsController < ApplicationController
  load_and_authorize_resource
  before_action :set_incident, only: [:show, :edit, :update, :destroy, :edit_override_score, :update_override_score]

  # ...

  def update_override_score
    override_params = params.require(:incident).permit(:score_override)
    override_params[:score_override] = nil if override_params[:score_override].blank?

    respond_to do |format|
      if @incident.update_attributes! score_override: override_params[:score_override]
        format.html { redirect_to @incident, notice: 'Incident was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit_override_score' }
        format.json { render json: @incident.errors, status: :unprocessable_entity }
      end
    end
  end

  # ...

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_incident
      @incident = Incident.find(params[:id])
    end
end

Any idea how this could possibly happen? You can see the incident hash right in the Parameters line of the log.

Upvotes: 1

Views: 149

Answers (1)

JustinBull
JustinBull

Reputation: 226

Thanks to Josh Leitzel, he pointed me in the right direction. I'm using the CanCan gem which is, at 1.6.10, has trouble with Rails 4. His comment explains the workaround.

I had to move the param.require() logic into a controller method incident_params however.

Upvotes: 1

Related Questions