ruby-on-railsruby

I try to create a carbon footprint calculator using ruby on rails 7. But I can't save and the user's object


Each person must select 4 options from a form to calculate a value. The form is the following:

<%= form_with(model: @carbon_footprint, local: true) do |form| %>
  <% CarbonFootprint::CATEGORIES.each do |category| %>
    <div class="field">
      <%= form.label category %>
      <%= form.select category, CarbonFootprint.emission_values[category].keys %>
    </div>
  <% end %>

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

My carbon footpring model:

class CarbonFootprintsController < ApplicationController

  def new
    @carbon_footprint = CarbonFootprint.new
  end
  
  def create
    @carbon_footprint = CarbonFootprint.new(carbon_footprint_params)
    @carbon_footprint.user = current_user
    if @carbon_footprint.save
      redirect_to @carbon_footprint, notice: 'Carbon footprint was successfully created.'
    else
      render :new, status: :unprocessable_entity
    end
  end

    private
  
    def carbon_footprint_params
      params.require(:carbon_footprint).permit(:plug_in, :get_around, :consume, :stay_warm_or_cool)
    end

end
  

my Carbon footprint model

class CarbonFootprint < ApplicationRecord
    belongs_to :user 
    validates :user_id, uniqueness: true

    CATEGORIES = [:plug_in, :get_around, :consume, :stay_warm_or_cool]

    def self.emission_values
        {
            plug_in: { fossil_fuel: 2.5, renewable: 0.5 },
            get_around: { fossil_fuel: 2.5, renewable: 0.5 },
            consume: { a_lot: 2.5, a_little: 0.5 },
            stay_warm_or_cool: { fossil_fuel: 2.5, renewable: 0.5 }
        }
    end


    def total
        total = 0.0
        self.class.emission_values.each do |category, options|
          total += options[self[category]]
        end
        total
      end
end

And my table

  create_table "carbon_footprints", force: :cascade do |t|
    t.float "plug_in"
    t.float "get_around"
    t.float "consume"
    t.float "stay_warm_or_cool"
    t.bigint "user_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["user_id"], name: "index_carbon_footprints_on_user_id"
  end

When I try do display the results this error occurs: nil can't be coerced into Float

And when I see how the object is saved to the database I see nil for every option.


Solution

  • In your select call in your view you're setting the options to CarbonFootprint.emission_values[category].keys which means the name AND VALUE of each option will be just the key itself, so eg. the value submitted in the form for plug_in will be either "fossil_fuel" or "renewable" not the actual numbers. You should drop the .keys and send the whole hash of { fossil_fuel: 2.5, renewable: 0.5 } etc.