sulleh
sulleh

Reputation: 331

Rails if statement error: "nil can't be coerced into Fixnum"

The application allows users to vote on a given lunch and score the overall performance of it. Each lunch is associated with a provider (restaurant) and when a user visits a provider's page, the user sees a history of all lunches associated with that particular provider. In turn, each provider is associated with a given cuisine. As the user votes up and down lunches, the :lunchscore value associated with @lunch is updated. In the providers/show.html.erb page, I'm trying to:

  1. Validate that a user has lunches associated with the provider
  2. Add up all the lunchescores for a given provider
  3. Divide the aggregate lunchscores by the number of lunches to get an average score

show.html.erb

<% @provider.lunches.count %>
<% if @provider.lunches.count > 0 %> 
       <% counter = 0 %>
       <% @lunches.each do |lunch| %>
       <% counter += lunch.lunchscore %> 
    <% end %>
<!-- counter = counter + lunch.lunchscore -->
    <% provider_score = counter / @provider.lunches.count.round %>
    <% end %>

provider.rb

class Provider < ActiveRecord::Base
belongs_to :cuisine
has_many :lunches
validates :name, presence: true, uniqueness: true
validates :cuisine, presence: true
end

lunch.rb

class Lunch < ActiveRecord::Base
belongs_to :provider
default_scope -> { order('created_at DESC') }
validates :date, presence: true, uniqueness: true
validates :provider_id, presence: true
end

And for completion's sake, here are my (truncated) controllers:

providers_controller.rb

  def show
    @provider = Provider.find(params[:id])
    @lunches = @provider.lunches
    @cuisine = @provider.cuisine
  end

  def create
    @provider = Provider.new(provider_params)
    if @provider.save
        flash.now[:success] = "New Provider Added!"
        redirect_to providers_path
    else
        render 'new'
    end
  end

lunches_controller.rb

  def create
    @lunch = Lunch.new(lunch_params)
        if @lunch.save 
            flash.now[:success] = "New Lunch Added!"
            redirect_to lunches_path
        else
            render 'new'
        end
    end
        private
            def lunch_params
                params.require(:lunch).permit(:date, :liked, :disliked, :enough, :not_enough, :provider_id, :lunchscore)
            end

When I attempt to do the above, I get this error: "nil can't be coerced into Fixnum" This errors on the line with <% counter += lunch.lunchscore %>.

Thinking that the code in the show.html.erb page breaks when there isn't an initial lunchscore set, I tried setting a value of 1 via form_for hidden_field, or writing 1 directly to the database in the lunchscore column. This didn't fix the issue.

I continue to suspect that the issue has something to do with datatypes or the logic in view, but I'm not sure.

Can anyone explain what this issue is, why is it crashing my application, and what conditional logic I can insert to prevent it from happening?

Upvotes: 0

Views: 149

Answers (1)

Eben Geer
Eben Geer

Reputation: 3796

You could avoid the exception like this:

<% counter += lunch.lunchscore if lunch.lunchscore %>

However, that entire loop should not be in view code, but probably on a model - probably Provider.

Upvotes: 1

Related Questions