I’m working on my first RoR project, and I want to build a form. The
tricky thing is, this form needs to insert / update against two models,
each with their own validation rules. Unfortunately, I’m having an
incredible amount of difficulty with the error handling, specifically
the fields wrapped in
The User class has_one :user_preference, and UserPreference belongs_to
:user. Both classes have a half dozen validation rules or so.
In my RegisterController, I have two actions: one to display the form,
and one to save the form.
Don’t laugh too hard at how ugly my code is, I’ve only read
Agile Web D. and Why’s Poignant Guide!
class RegisterController < ApplicationController
def index @user = User.new @pref = UserPreference.new @user.user_preference = @pref end def save @user = User.create(params[:user]) @pref = UserPreference.create(params[:user_preference]) @user.user_preference = @pref # Default display name to something nice @user.user_preference.display_name = @user.username User.transaction do if @user.save and @user.user_preference.save # do something useful else # breakpoint('User not saved.') render(:action => 'index') end end # end transaction end # end save
I also have a template that renders my partial template for the new user
form. Yes, it does use the form helper functions to generate fields:
<%= text_field ‘user’, ‘username’, ‘maxlength’ => 20, ‘size’ => 20 %>
<%= text_field ‘user_preference’, ‘email’, ‘size’ => 20, ‘maxlength’ =>
When the form is submitted, both sets of validation rules are run. The
standard error_messages_for, however, only supports rendering out the
errors from one model’s validation. I fixed this with a (really hackish)
helper. It take in an array of instance variables and build the error
box for them.
But, the remaining issue I am unable to solve: . Rails only wraps the tags that fail the
User class’ validation. I’ve been unable to grok how Rails figured out
which fields it needs to put in the fieldWithErrors divs, even after
reading a whole lot of Rails source.
What would an optimal solution be? Can I insert my own code anywhere to
take over this part of error handling? Or, failing that, is there a way
I can disable the wrapping of elements in fieldWithErrors for only this
Thank you all very much!