Saturday, April 30, 2011

Trouble with foreign keys

So I've been doing some work on Manticore (previously Dungeon Roller) and I'm stuck. SURPRISE!

Here's the problem: I have two models, character and statistic. Each instance of the character model will have one instance of the statistic model associated with it. I've got the code set up so that I can create new characters with no problem, but all characters are using the same instance of the statistic model. I think this is because I don't have the foreign keys set up correctly and that's largely because I don't know HOW to set up the foreign keys. I know what they are, and for the statistic model I need to use character_id, right? But I don't get how to use it, or how to associate these models so that each character will have one statistic model.

I've spent some time on stack overflow today and got some good feed back, but I'm having trouble finding out how to do exactly what I want. Going over the code I've done through various tutorials isn't helping, either.

Here's what I have for the character model:

class Character < ActiveRecord::Base &nsbp: has_many :statistics, :dependent => :destroy

And here's the statistic model:

class Statistic < ActiveRecord::Base
  belongs_to :character

My friend Eli's told me I need to associate this as @character.statistic, which makes sense, but I'm still not getting it. Where does this code go? I know the bulk of the logic needs to go in the models, but what about the controllers? I feel fairly confident I can actually display the information in the view once I get it straightened out on the back end. At that point, it'd just be a matter of a link_to or a render tag, right?

Any help is highly appreciated. I've done similar things with the shopping cart application I'm building with Agile Web Development, but I'm having a hard time connecting the dots and extrapolating what I need to do in this case.


  1. Your associations look fine. You won't need to use the foreign key options to has_many/belongs_to because you are using the standard name (character_id on Statistic).

    So, I think what is happening is that your Statistic model has the character_id set to NULL, or all your statistics have their character_id set to the same thing.

    Easiest way to test this is open up the Rails console and take a peek.

    pp Statistic.all # pp is "pretty print"

  2. I think all the statistics had their character_id set to the same thing. Either way, I restarted (again!) and followed the blog tutorial more closely. Not a good habit to get into, but I was able to fix the problem. Now I have new, more exciting problems!

    Still, it's been good. I kept the old code for reference and I'm more familiar with partials now. Do you use Rails console a lot? Do you keep it running all the time? Is it good for diagnostics, or what? I'm guessing it helps you pinpoint where problems are as they arise, but I'm not sure how it differs from running the terminal.

  3. I use rails console very frequently. It's great for doing quick "is this how it works?" tests and rooting around in your application.

    I run it as-needed, but it often has it's own tab that lives for many hours.

    Rails console runs inside the terminal, and it gives you the ability to interactively try code without using the web interface. Being familiar with it will be a big help.

    Here are some great uses:

    What happens if I call pretty_name on a User that has a name in all uppercase? => 'TYLER MOORE').pretty_name

    How many users does the production server have? User.count

    What are the subclasses of my Post model? Post.subclasses

    How many comments don't have a user? Comment.count(:conditions => { :user_id => nil })

  4. @Eli yeah, I've fired up Rails console before but haven't dug too deeply into what it can do. Now it's obvious I need to get a handle on working with it. Basically you can use it to interact with the database independent of the application as well as figuring out how code will behave?

  5. Basically yes. Although you should consider it as interacting with the application through it's server-side API instead of UI. Eventually you'll have more things than a database connected, email, sms, queues, etc.