I was wondering if someone can see the obvious error I am making. I can't see it.
My Rails 7.2 application relies on an enum for :likelihood and :consequence. Unfortunately, in testing, I am getting an error.
I have followed this article exactly https://blog.saeloun.com/2021/02/26/rails-introduces-new-syntax-for-enum/ and can't see why i am getting the argumenterror.
I am sure I have made a simple error somewhere, but i just cant see it.
I have layed out the error, model, controller and form below. Let me know if you require more info.
thank you in advance
The Error
09:43:32 web.1 | Processing by PotentialHazardsController#create as TURBO_STREAM
09:43:32 web.1 | Parameters: {"authenticity_token"=>"[FILTERED]", "potential_hazard"=>{"description"=>"test dws", "likelihood"=>"4", "consequence"=>"4", "procedure_id"=>"1"}, "commit"=>"Create Potential hazard"}
09:43:32 web.1 | Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms (0 queries, 0 cached) | GC: 0.2ms)
09:43:32 web.1 |
09:43:32 web.1 |
09:43:32 web.1 |
09:43:32 web.1 | ArgumentError ('4' is not a valid consequence):
09:43:32 web.1 |
09:43:32 web.1 | app/controllers/potential_hazards_controller.rb:24:in `create'
The Model
class PotentialHazard < ApplicationRecord
belongs_to :procedure
has_many :management_methods
enum :likelihood, [ :rare, :unlikely, :possible, :likely, :almost_certain ], prefix: true, scopes: false
enum :consequence, [ :insignificant, :minor, :moderate, :major, :catastrophic ], prefix: true, scopes: false
end
The Controller
class PotentialHazardsController < ApplicationController
before_action :set_potential_hazard, only: %i[ show edit update destroy ]
# POST /potential_hazards or /potential_hazards.json
def create
@potential_hazard = PotentialHazard.new(potential_hazard_params)
respond_to do |format|
if @potential_hazard.save
format.html { redirect_to @potential_hazard, notice: "Potential hazard was successfully created." }
format.json { render :show, status: :created, location: @potential_hazard }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @potential_hazard.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /potential_hazards/1 or /potential_hazards/1.json
def update
respond_to do |format|
if @potential_hazard.update(potential_hazard_params)
format.html { redirect_to @potential_hazard, notice: "Potential hazard was successfully updated." }
format.json { render :show, status: :ok, location: @potential_hazard }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @potential_hazard.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_potential_hazard
@potential_hazard = PotentialHazard.find(params[:id])
end
# Only allow a list of trusted parameters through.
def potential_hazard_params
params.require(:potential_hazard).permit(:description, :consequence, :likelihood, :procedure_id, :position)
end
end
The Form
<%= form_for @potential_hazard do |form| %>
<% if @potential_hazard.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@potential_hazard.errors.count, "error") %> prohibited this potential_hazard from being saved:</h2>
<ul>
<% @potential_hazard.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-floating mb-3">
<%= form.text_field :description, id: "description",class: 'form-control', placeholder: 'Describe the potential hazard' %>
<label class="form-label" for="description">Description</label>
</div>
<div class="form-floating mb-3">
<%= form.select :likelihood, options_for_select(PotentialHazard.likelihoods.map {|k, v| [k.humanize.capitalize, v]}), {include_blank: false }, {class: 'form-select'} %>
<label class="form-label" for="description">Potential Hazard Likelihood</label>
</div>
<div class="form-floating mb-3">
<%= form.select :consequence, options_for_select(PotentialHazard.consequences.map {|k, v| [k.humanize.capitalize, v]}), {include_blank: false }, {class: 'form-select'} %>
<label class="form-label" for="description">Potential Hazard Consequence</label>
</div>
<%= form.hidden_field :procedure_id, value: procedure.id %>
<div class="mb-3">
<%= form.submit class: 'btn btn-primary' %>
</div>
<% end %>
The Migratrion/DB
create_table "potential_hazards", force: :cascade do |t|
t.string "description"
t.bigint "procedure_id", null: false
t.integer "position"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "likelihood", default: 0
t.integer "consequence", default: 0
t.index ["procedure_id"], name: "index_potential_hazards_on_procedure_id"
end
You need to send value from enum's list
Instead of 4
- send catastrophic