if else statement

Hi I am doing a basic if..else statement and keep getting exceptions both of these are stored as int's

<% if schedule.for>schedule.against %>                       <strong>W</strong>                   <% elsif schedule.for<schedule.against %>                       <strong>L</strong>                   <% else %>                       <strong>T</strong>                   <% end %>

NoMethodError in Schedules#index

Showing /Users/*****/Sites/rails_projects/*****/app/views/schedules/index.html.erb where line #47 raised:

undefined method `>' for nil:NilClass Extracted source (around line #47):

44: <tr> 45: <td><%= schedule.location %></td> 46: <td> 47: <% if schedule.for>schedule.against %> 48: <strong>W</strong> 49: <% elsif schedule.for<schedule.against %> 50: <strong>L</strong>

Hi I am doing a basic if..else statement and keep getting exceptions both of these are stored as int's

<% if schedule.for>schedule.against %> <strong>W</strong> <% elsif schedule.for<schedule.against %> <strong>L</strong> <% else %> <strong>T</strong> <% end %>

NoMethodError in Schedules#index

Showing /Users/*****/Sites/rails_projects/*****/app/views/schedules/index.html.erb where line #47 raised:

undefined method `>' for nil:NilClass Extracted source (around line #47):

44: <tr> 45: <td><%= schedule.location %></td> 46: <td> 47: <% if schedule.for>schedule.against %>

The clue is in the error message. It is telling you the schedule.for is nil (or possibly schedule.against, I am not certain).

Have a look at the Rails Guide on debugging for suggestions on how to debug code. I see to have an attack of deja vu.

You might be better defining a model method which returns the appropriate character dependent on for and against then you can remove the if..else from the view. Logic in views is best avoided whenever possible.

Colin

The error is telling you that the thing you are calling "greater than" on is nil. Looking at line 47, that thing is "schedule.for" - this value, although you *think* it may be an integer is nil.

First off, look into debugging your app to get to the bottom of these issues faster for yourself:

Secondly, a bodge fix would be to call "to_i" on the values before you compare them:     <% if schedule.for.to_i > schedule.against.to_i %>

Thirdly. this sort of logic should really live in the model, or a helper (or split between both), certainly not in the view.

#Schedule model def win_lose_tie   return :tie if if schedule.for.to_i == schedule.against.to_i   schedule.for.to_i > schedule.against.to_i ? :win : :lose end

#helper def win_lose_tie_display(value)   case value   when :win     "W"   when :lose     "L"   when :tie     "T"   else     "unknown win/lose/tie value"   end end

#view <strong><%= win_lose_tie_display(schedule.win_lose_tie) %></strong>

Thanks Michael, though i would have thought if its greater than nil it would still output my response

Hi Michael, I have tried the code you suggested, though all i seem to get is every result as a tie. this is what I have in my

#model def win_lose_tie     return :tie     if if schedule.for.to_i == schedule.against.to_i          schedule.for.to_i > schedule.against.to_i ? :win : :lose        end     end

  end

#view <strong><%= win_lose_tie_display(schedule.win_lose_tie) %></strong>

#helper def win_lose_tie_display(value)     case value       when :win         "W"       when :lose         "L"       when :tie         "T"       else         "unknown win/lose/tie value"     end   end

i even tried what you would do in php and had a variable set us :result to return though it gave me a value of unknown win/lost

thanks

Hi Michael, I have tried the code you suggested, though all i seem to get is every result as a tie. this is what I have in my

#model def win_lose_tie return :tie

It is not surprising that you always get :tie if this is the first line in the method. Go back and look at Michaels code again and pay attention to newlines. There should be only one 'if' however which may have confused you. It is important to make sure you understand code that someone suggests rather than just using it. If you cannot understand it then work through some Ruby tutorials and if you still cannot understand it then ask for clarification.

Also both Michael and myself suggested looking at the Rails Guide on debugging, did you do this? If so what did you learn when you used those techniques to debug your code?

Colin

Hi Michael, I have tried the code you suggested, though all i seem to get is every result as a tie. this is what I have in my

#model def win_lose_tie return :tie if if schedule.for.to_i == schedule.against.to_i schedule.for.to_i > schedule.against.to_i ? :win : :lose end end

end

Hiya,

The code I posted was a rough, un-run, first draft typed straight into the email client, but even so, I did a little re-arrangement and DRYing while composing, and left an extraneous "if" on the first line of win_lose_tie. This is what it should look like (the if condition at the end of the line is a modifier, or "guard" - not a construct that PHP supports AFAIK :wink:

  def win_lose_tie     return :tie if schedule.for.to_i == schedule.against.to_i     schedule.for.to_i > schedule.against.to_i ? :win : :lose   end

Bear in mind that I haven't run it - so it may need a little debugging. The intention of my post is that you see more clearly the direction the code should be heading towards (rather than having huge logical constructs in your views).

i even tried what you would do in php and had a variable set us :result

To be honest, I don't really see how "trying in PHP" is going to go any way to solving a problem you have in Ruby - it's certainly not one of the first debugging steps I would recommend :-/

thanks for the tips, i cleaned up the code a bit, and used some other logic which produced this

def win_lose_tie     if self.for.to_i == self.against.to_i then       :tie     elsif self.for.to_i > self.against.to_i then       :win     else       :lose     end   end

So you turned a Ruby two line method into a PHP 7-liner? If you prefer....

Well, as long as you see the direction the code should go, you can always make it more "Ruby" later :wink:

This could even be a one-liner... but maybe not for a beginner:

def wld(me,him)   [:lose, :draw, :win][(me <=> him) + 1] end

:slight_smile:

-Dave