Mike
Mike

Reputation: 5193

time_select() helper + jQuery UI datepicker

I have a form with a time_select and a jquery datepicker,

I want to be able when I submit the form to merge the values of the time_Select and the datepicker into one datetime of my ActiveRecord model ...

Is there an elegant way to do that ? Should I do it client or server side ... I'd like to keep my action as simple as that :

  def create
    @drive = Drive.new(params[:drive]))
    if @drive.save
      flash[:notice] = 'Drive created !'
      render :action => :show 
    else
      render :action => :new
    end
  end

I don't know ... should I do it with virtual attributes in the model and merge them before_save or maybe in javascript when the form is submit or maybe you have a better idea ... What do you think ??

Thanks,

Mike.

Upvotes: 1

Views: 1104

Answers (1)

EmFi
EmFi

Reputation: 23450

The short answer is: It doesn't matter, they're equally good.

You have 3 reasonable places you could handle this.

  1. In the client with javascript on submit.
  2. In the controller.
  3. In the model.

Regardless of what method you use, you will have to process the data in the controller/model because all parameters are received as strings.

In the model and controller variants you have an extra decision to make. Piece together the DateTime from 6 fields or use a pair of strings (one containing the value, one containing the strptime format.)

Knowing that DateTime's constructor methods require about the same amount of work to build a datetime object from set of separate fields as it does to build the object from a datetime string and a format string. It really doesn't matter how you build the DateTime object.

So it all boils down to a matter of personal preference.

Personally I believe this logic belongs in the model. I wouldn't put it in the javavascript because I like to ensure that my code doesn't break if Javascript is disabled. The controller is an equally good fit. But I feel offloading this logic to the model allows for more robust handling of dates and validations. I also find the strptime constructor much easier to read than the 7 argument civil constructor. But the civil constructor doesn't require me to ensure format hours/minutes/seconds are exactly 2 digits long. Either way I would be passing year, month, day, hour, minute and second offset as separate attr_accessors fields, so I that data available for processing if necessary.

Example code

class Drive < ActiveRecord::Base
  ...
  attr_accessor :year, :month, :day, :hour, :minute, :second, :locale_offset

  before_validation :build_date
  validates :future_time

  def build_date
    begin 
      self.date  = DateTime.civil( year.to_, month.to_i, day.to_i,
                     hour.to_i, minute.to_i, second.to_i, user.locale_offset)
    rescue 
      errors.add(:date, "Invalid date")
      return false
    end  
  end

  def future_time
    unless date > DateTime.now 
      errors.add(:date, "Date occurs in the past.")
    end
  end
end

Upvotes: 3

Related Questions