Validates_presence_of *_id attributes

Hi all,

I am a newbie to Rails. Please enlighten me on how to do this
appropriately, the Rails and the Ruby way:

Suppose I have a Recipe model. Let’s simplify things and pretend that
it has only 2 attributes, a :name and the other is a ‘category_id’. In
the recipes table, category_id is a foreign key to field id of table
categories.

We also assume that I have generate the appropriate scaffolding code
for Recipe and Category. All goes well if I go to
http://localhost:3000/categories (I’m using WEBrick) and add a new
Category and then go to http://localhost:3000/recipes and add a Recipe
and choose a category for the recipe.

What if I go to http://localhost:3000/recipes first and add a new
recipe without specifying a category (note that I enforce the
category_id field in the recipes table to be not null). Rails will
definitely complain.

Is there somekind of “validates_presence_of” for *_id kinds of field
thus the user of my application can be notified to make a category
first before adding recipe?

Tq very much,
John

John,

Check out ‘validates_associated’

http://api.rubyonrails.com/classes/ActiveRecord/Validations/
ClassMethods.html#M000689

Chris Nolan.ca
http://kweschun.com/ - Do you have a kweschun?

On 1/3/06, Chris Nolan.ca [email protected] wrote:

John,
Check out ‘validates_associated’
Chris Nolan.ca

Hey, thanks for the response. Thanks for introducing me to
validates_associated too. However, after updating my Recipe model
with:
validates_associated :category
, the error is still there. I’m afraid that this doesn’t have anything
to do with validating association, here’s the error:

“You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.inject”

I think this is because I use
<%= collection_select ‘recipe’, ‘category_id’, @categories, ‘id’,
‘description’ %> in _form.rhtml
and by the time I intentionally create a new recipe, there is not even
a single category.

How to handle this the Rails way?
Tq.

in your Recipe model, you just do:

validates_presence_of :name, :category_id

now as far as “before” adding a recipe, the app isn’t going to know you
haven’t selected anything until you submit the form, then your app will
do
the validation before the save. if the validation fails, you can have
your
app notify the user using something like:

<%= error_messages_for(:recipe) %> in your “New Recipe” view.

of course, you could always use javascript to validate your form before
you
submit it.

now if your problem is that there are no pre-existing categories, you
might
want to think about adding a few default to the app or allow the user to
create a new category when they are creating a new recipe. if a
category is
nothing more than a name like “Dessert” or whatever, just add

<%= text_field_tag “new_category_name”, “” %>

in your create/edit form view and in your create/update controller
methods,
do a check on this field…if the user entered a new category, create
that
category then use it to create the recipe.

Chris H. wrote:

in your Recipe model, you just do:

validates_presence_of :name, :category_id

Actually, I suggest you use

validates_presence_of :category

Because the category association will use the category_id column to try
and get
the Category object, you’ll end up checking if the category_id is not
nil and if
it is not nil, it’ll also try to load the associated row from the
Category
table. If that row doesn’t exist for the category_id, then you’ll also
get a
validation error. So you get two checks for one line of code.

Regards,
Blair


Blair Z., Ph.D.
[email protected]
Subversion and Orca training and consulting
http://www.orcaware.com/svn/