Sunday, September 18, 2011

Nil can't be coerced into Fixnum in Rails

Question time!

I'm trying to figure out a way to calculate bonuses or penalties from a Character's Statistics, and then apply that method in other Models' views to calculate things like Fortitude saves, attack bonuses and so on. I've been working with a modifier for Constitution and here's what I've got so far.

The logic for calculating a Statistic bonus/penalty is (statistic - 10) / 2. So for a score of 14, we get 2, and for a score of 8, we get -1. Not bad so far!

So I define this method in Statistic controller:

def con_modifier
  (constitution.to_i - 10) / 2

And since I want to see it in my Character view, I wire it up in the Show method in Characters controller as such:

@con_modifier = @character.statistic.con_modifier

So I can see it in my Character view (where most of this information is displayed) and I know it's working so far. I've got a Fortitude model for Fortitude saves, and I'd like to use the con_modifier in the logic to calculate a total. How do I call a foreign model correctly this way? I have:

Here's the logic for calculating a total in my Fortitude model right now:

def total
  fortitude_base.to_i + ability.to_i + magic.to_i + misc.to_i

And I tried changing it to:

def total
  fortitude_base.to_i + @con_modifier + magic.to_i + misc.to_i

But then I get this error:

nil can't be coerced into Fixnum

So obviously it isn't calling up the correct information. I've noticed if I chage @con_modifier to @con_modifier.to_i, it calculates it at 0, because it's nil. Any ideas on how to call the number that actually exists? Do I need to define it in my Fortitudes controller as well, or can I simply define it in the Fortitude model and call it in the view that way?


  1. Variables that begin with @ are instance variables, meaning they're only available to things within the same instance of that object. So setting @con_modifier in your controller means it won't be available within your Fortitude model. I think you probably want something like statistic.con_modifier instead of @con_modifier.

    All the to_i's seem like a code smell. They shouldn't be necessary and suggest that there is a deeper problem. When I get back to Indy we should get together and re-hash out the design of your app :)

  2. @Eli I mostly have the to_i's in there per Matt's suggestion for fixing my validation, and I don't think they're necessary. Maybe a bit of paranoia on my part? The code WAS working fine without them, and the validation ensures that values entered in the form are integers, so I can likely take them out.

    And statistic.con_modifier isn't working either. Rails complains about an "undefined local variable or method `statistic' " when I define the method in the Fortitude model. Do I also need to define it in the controller? Where IS something defined when Rails complains about undefined variables?

    Also I am down for hanging out and coding and drinking beers (I assume beers is implied)