dimanche 22 mars 2015

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

I am building a simple web application to teach myself rails - so I apologize if I use the incorrect language and terminology. I'm encountering an unusual edge case with my application that is generating a nasty error.


App Background The application allows users to vote on a given lunch, and score the overall performance of a lunch. Each lunch is associated with a provider (think restaurant) and when you visit a provider's page, you see a history of all lunches associated with that particular provider. In turn, each provider is associated with a given cuisine.


As you vote up and down lunches, you update the :lunchscore value, associated with the @lunch. In the providers/show.html.erb page, I'm trying to:



  1. Validate that you have 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.


My Issue When I attempt to do the above, I get this error: "nil can't be coerced into Fixnum" This errors out on line 14, which in the view below is the line with <% counter += lunch.lunchscore %> on it.


Thinking that the code below 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 a "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?


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

Aucun commentaire:

Enregistrer un commentaire