Wednesday, September 21, 2011

Instance variables and local variables in Rails

I've got a lot to learn about local and instance variables. I already knew 'character' meant a local instance of character, but I thought '@character' referred to another model, and not an instance of the Character model. I knew that sometimes if Rails was complaining about an unidentified local variable, putting an @ in front would often fix the problem, but I didn't know why. I think I've got a better handle on this, but I think the time has come to do some serious background reading to try and patch up some of the holes in what I know and what I think I know.

On the other hand, thanks to help from @jqr and a healthy does of trial and error, I've gotten that pesky statistic bonus problem figured out. This is what ended up working:

def total
  fortitude_base + character.statistic.con_modifier + magic + misc
end

And here's the con_modifier definition from my Statistic model:

def con_modifier
  (constitution.to_i - 10) / 2
end


I'm keeping it as .to_i now, as a fix for a case where a player tries to create a Fortitude save before a Constitution score has been entered. The .to_i translates a nil record to 0, so Rails does a temporary calculation (which isn't shown) rather than displaying an error. Not sure if there's a better way to handle this (perhaps simply checking that statistic.constitution.present? before performing any calculations) but it works for now.

More importantly than simply figuring this one instance of how to define logic in one model and then call it in the view of another is understanding HOW it works. I can extrapolate these methods and apply them to other things: skills, attack rolls, armor class, etc, etc. Once again, Manticore proves to be a useful learning tool! SUCCESS!

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
end

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
end

And I tried changing it to:

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

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?