On Feb 24, 3:27 pm, Valery Kvon <[email protected]> wrote:
> On 24.02.2012, at 23:38, David M wrote:
>
> > How can I validate a date that is set with select boxes on the form, so I 
> > can raise an error when it's invalid?
>
> > The default behavior when an invalid date is entered is to add days to 
> > arrive to a valid date. For example: if 2012-31-06 is sent to the 
> > controller, the resulting date will be 2012-01-07
>
> > How can I stop this behavior and raise an error?
>
> > I'm using the date_select(object_name, method, options = {}, html_options = 
> > {})method in the view.
>
> Interesting question.
>
> In the case when date_select helper used, it automatically generates 
> parameter keys:
> 'date(1i)' - year
> 'date(2i)' - month
> 'date(3i)' - day
>
> When ActiveRecord model receives these parameters, Date object will be 
> generated and assigned to a corresponding model's attribute. In this process, 
> there is its clever logic: when values of these parameters aren't clearly 
> 'crazy', Date object will be generated correctly without attention to the 
> minor errors in the number of days (28, 30 or 31) without any validation 
> errors.
>
> To avoid this integrated logic you can put down your own model's accessors 
> for 'date(1i)', 'date(2i)', 'date(3i)' mass-assignment parameters and 
> appropriate custom validator. Or you can hack 
> ActiveRecord::MultiparameterAssignment stack to escape its logic. Both are 
> unaesthetic, unclean approaches from all points of view.
>
> Instead of 'date_select', you can use 'select_date' (render just the tag), in 
> this case date parameters will be named as you want. Just write the accessors 
> and attribute assignment logic, then put the custom validator and this is it.
>
> As for me, I completely gave up date_helper and other selectors, and began to 
> use strings for dates in a form, adding to their Jquery

I also used strings, as it is much easier to enter a date with text
than picking each field from the dropdowns. I made it so that if you
enter a full year, fine. But if you do a 1 or 2 digit year it will
pick the rest of the year correctly. If you have 130 year old dates
you will have to enter all 4 digits.

here's the code
model>

  before_validation :b4_valid

  def b4_valid
    self.xmonth = self.month_.to_i
    self.xday = self.day_.to_i
    self.xyear = self.year_.to_i
    begin
      if (self.xyear >= 0 && self.xyear <= 100)
        @compare = Date.new(2000+self.xyear, 1,1)
        if (@compare > Date.today)
          self.xyear = 1900+self.xyear
          self.year_ = self.xyear.to_s
        else
          self.xyear = 2000+self.xyear
          self.year_ = self.xyear.to_s
        end
      end
    rescue
      return false
    end
    begin
      self.birthday = Date.new(self.xyear, self.xmonth, self.xday)
    rescue
      return false
    end
  end

view>
<% fields_for "household[people_attributes][]", person do |
person_form| %>
<div><tr>
        <% fields_for "household" do |household_form| %>
                <td><%= household_form.radio_button :hoh, person.hoh %></td>
        <% end %>
        <%= person_form.hidden_field :hoh, :index => nil %>
<td><%= person_form.text_field :last_name, :style => 'text-align:
left', :class => 'last_name', :size => 25, :maxlength => 25, :index =>
nil, :autocomplete => "off"  %></td>
<td><%= person_form.text_field :first_name, :style => 'text-align:
left', :class => 'first_name', :size => 25, :maxlength =>25, :index =>
nil, :autocomplete => "off"  %></td>
<td><%= person_form.text_field :middle, :style => 'text-align:
right', :class => 'middle', :size => 1, :maxlength =>1, :index =>
nil, :autocomplete => "off"  %></td>
<td><%= person_form.text_field :sex, :style => 'text-align:
right', :size => 1, :maxlength =>1, :index => nil, :autocomplete =>
"off"  %></td>
<td><%= person_form.text_field :month_, :style => 'text-align:
right', :size => 2, :maxlength =>2, :index => nil, :autocomplete =>
"off" %></td>
<td><%= person_form.text_field :day_, :style => 'text-align:
right', :size => 2, :maxlength =>2, :index => nil, :autocomplete =>
"off" %></td>
<td><%= person_form.text_field :year_, :style => 'text-align:
right', :size => 4, :maxlength =>4, :index => nil, :autocomplete =>
"off" %></td>
<td><% if !person_form.object.new_record? %>
        <%= person_form.hidden_field :id, :index => nil %>
        <%= link_to 'Delete', person_path(person.id),  :confirm => 'Are you
sure?', :method => :delete %>
<% end %></td>
</tr></div>
<% end %>

This will calculate the date object based on the input and fail
validation if the date is incorrect. Because of the rescue statements,
there should be no errors that cause the program to abort. All errors
will show as validation failures.


Best of luck
Bob <[email protected]>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en.

Reply via email to