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

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,


Check out ‘validates_associated’

Chris - Do you have a kweschun?

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

Check out ‘validates_associated’

Hey, thanks for the response. Thanks for introducing me to
validates_associated too. However, after updating my Recipe model
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?

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
the validation before the save. if the validation fails, you can have
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
submit it.

now if your problem is that there are no pre-existing categories, you
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
do a check on this field…if the user entered a new category, create
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
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.


Blair Z., Ph.D.
[email protected]
Subversion and Orca training and consulting

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs