Tuesday, August 16, 2011

Validation errors in Rails

Whoa! I've been chugging along with Manticore the last 5 days or so and making some good progress. However, I've hit another wall (can you believe it?)

Basically here's the problem. I have a model Ac that creates Armor information for a Character. I've created some methods to calculate various data from fields from a Character's Ac model, and to avoid any errors when doing these calculations I need to validate presence_of and numericality_of several fields.

So my problem is two-fold. First off, when creating the Ac, all of the validation errors appear before the user has attempted to enter any data. Furthermore, the user can still create an Ac with no data at all. Clearly my validation isn't working.

Here's the code itself from my Ac model:

class Ac < ActiveRecord::Base
belongs_to :character
validates_presence_of :base_ac, :armor, :shield, :dex, :size, :natural, :misc, :deflection validates_numericality_of :base_ac, :armor, :shield, :dex, :size, :natural, :misc, :deflection

...
end


And the code from my AcsController:

class AcsController < ApplicationController
def new
  @character = Character.find(params[:character_id])
  @ac = @character.create_ac(params[:ac])
end

def edit
  @character = Character.find(params[:character_id])
  @ac = @character.ac
end

def create
  @character = Character.find(params[:character_id])
  @ac = @character.ac(params[:ac])
  redirect_to character_path(@character), :notice => 'Armor Class was successfully created.'
end

def update
  @character = Character.find(params[:character_id])
  @ac = @character.ac
  if @ac.update_attributes(params[:ac])
    redirect_to character_path(@character), :notice => 'Armor Class was successfully updated.'
  else
    render :action => "edit"
    end
  end

end

I'm not sure what could be causing this problem. I've got similar validation for the Character model and it works fine. Any advice? The form_for a new Ac is rendered from a partial in the Character show page, but I'm not sure if that would have an effect on this.

Also, on a slightly tangential note, when rendering a form like this, is that what's meant by a "nested form" ? I've seen this term a few times while searching for a solution and I'm unclear as to what it means.

Here's a link to the project on Github: https://github.com/illbzo1/Manticore

2 comments:

  1. line 5 of acs_controller.rb should be:
    @ac = @character.build_ac
    instead of:
    @ac = @character.create_ac(params[:ac])

    and line 15 should be:
    @ac = @character.create_ac(params[:ac])

    acs_controller#new should just be setting up a naked object with no attributes when it renders the new form, but the way you had it, it was trying to create the ac with params[:ac], which is nil because there are no params., so it tried to create it, and it failed validation, so it showed you the validation errors.

    The issue with "create" is the way it was:
    @ac = @character.ac(params[:ac])
    would look for a method on the Character model named ac and pass the params into that, but you don't have a method like that, and it is not very idiomatic anyway. Probably an oversight, but worth pointing out.

    Also, I noticed that there is no migration to add the "acs" table, so "rake db:migrate" didn't bring my database up to date. I had to do "rake db:schema:load".

    Anyhow, I'm glad to see you are still at it and making progress!

    ReplyDelete
  2. Awesome, this code cleans up most of my issues. I'm still able to create a blank Ac without the validation complaining. It DOES complain if I go to edit an existing Ac and delete a value, but the validation still isn't triggering upon creation.

    I think what happened with not having a migration to create acs is it used to be called armors and then I changed it because it was confusing me. So I must have deleted that migration by accident?

    Thanks for the encouragement. I've definitely made progress and I know enough now to figure a lot of things out, but I still run into roadblocks.

    From what I understand, that's a coding thing, not a newbie thing, though.

    ReplyDelete