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:
http://guides.rubyonrails.org/debugging_rails_applications.html

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