Question: I have a date field in a model backed form in my Rails App:

```
<%= f.date_select :birthday,
  {:start_year => Time.now.year,
  :end_year => 1900,
  :use_short_month => true,
  :order => [:month, :day, :year],
  :prompt => {:month => 'Month', :day => 'Day', :year => 'Year'}},
  {:class => 'year',
  :id => 'user_birthday'}
%>

```

It is being validated in the model code using:

```
validates_presence_of :birthday, :message => 'is a required field'

```

Unfortunately, if the user enters a partial value such as just the year, the form still submits without an error. Instead a funky date value gets written to the db. How do I make all three fields be mandatory?

I'd like to write a custom validation for this, but I don't know how to properly access the indvidual pieces of the birthday element. How can I do this?

Thanks!
Moe

Answer: 
I think you would have to create the validation in the controller itself.

The date parts are being passed to `birthday(1i)`, `birthday(2i)` and `birthday(3i)`. The problem here is that they are assigned immediately when passing the attributes and thus before any validations occur.

You could also overwrite the `attributes=` method to create your own validation there, but I would not suggest you to do that.

Keep in mind that if you do validations, it might be good to validate against any incorrect date as well. (for instance 31st of February, which when passed will yield 2nd of March and not an error).

I think the main issue here is that ActiveRecord is actually replacing the empty values with `1` before creating the `Date`, which also means that if the visitor pass only the year, the date will be created on the 1st of January that year. I guess that is an expected behaviour to allow use of only one of year/month/day select and still create a useful date.
You could override the `validate_on_create` method, like the following:

```
class MyModel < ActiveRecord::Base
  def validate_on_create
    Date.parse(birthday)
  rescue
    errors.add_to_base("Wrong date format")
  end
end

```