views:

3696

answers:

4

How would you go about producing reports by user selected date ranges in a rails app? What are the best date range pickers?

edit in response to patrick : I am looking for a bit of both widget and active record advice but what I am really curious about is how to restfully display a date ranged list based on user selected dates.

+14  A: 

Are we asking an interface question here (i.e. you want a widget) or an ActiveRecord question?

Date Picking Widgets

1) Default Rails Solution: See date_select documentation here.

2) Use a plugin : Why write code? I personally like the CalendarDateSelect plugin, using a pair of the suckers when I need a range.

3) Adapt a Javascript widget to Rails: It is almost trivial to integrate something like the Yahoo UI library (YUI) Calendar, which is all Javascript, to Rails. From the perspective of Rails its just another way to populate the params[:start_date] and params[:end_date]. YUI Calendar has native support for ranges.

Getting the data from the Widgets

1) Default Rails Solution See date_select documentation here.

#an application helper method you'll find helpful
#credit to http://blog.zerosum.org/2007/5/9/deconstructing-date_select

# Reconstruct a date object from date_select helper form params
def build_date_from_params(field_name, params)
  Date.new(params["#{field_name.to_s}(1i)"].to_i, 
       params["#{field_name.to_s}(2i)"].to_i, 
       params["#{field_name.to_s}(3i)"].to_i)
end

#goes into view
<%= date_select "report", "start_date", ... %>
<%= date_select "report", "end_date", ... %>    

#goes into controller -- add your own error handling/defaults, please!
report_start_date = build_date_from_params("start_date", params[:report])
report_end_date = build_date_from_params("end_date", params[:report])

2) CalendarDateSelect: Rather similar to the above, just with sexier visible UI.

3) Adapt a Javascript widget: Typically this means that some form element will have the date input as a string. Great news for you, since Date.parse is some serious magic. The params[:some_form_element_name] will be initialized by Rails for you.

#goes in controller.  Please handle errors yourself -- Javascript != trusted input.
report_start_date = Date.parse(params[:report_start_date])

Writing the call to ActiveRecord

Easy as pie.

  #initialize start_date and end_date up here, by pulling from params probably
  @models = SomeModel.find(:all, :conditions => ['date >= ? and date <= ?',
    start_date, end_date])
  #do something with models
Patrick McKenzie
A bit of both widget and active record but what I am really curious about is how to restfully display a date ranged list based on user selected dates. Specifically, how best to get the input from the user into the active record find.
srboisvert
I've taken the liberty of expanding my answer to be more helpful to you.
Patrick McKenzie
shouldn't build_date_from_params go into the application controller rather than the application helper?
inglesp
+2  A: 

It's not an unRESTful practice to have URL parameters control the range of selected records. In your index action, you can do what Patrick suggested and have this:

  #initialize start_date and end_date up here, by pulling from params probably
  @models = SomeModel.find(:all, :conditions => ['date >= ? and date <= ?', params[:start_date], params[:end_date]])

Then in your index view, create a form that tacks on ?start_date=2008-01-01&end_date=2008-12-31 to the URL. Remember that it's user-supplied input, so be careful with it. If you put it back on the screen in your index action, be sure to do it like this:

Showing records starting on 
<%= h start_date %> 
and ending on 
<%= h end_date %>
Pete
A: 

Thank you, Patrick and Pete! It is a problem that i face My answer is in fact a question to both Patrick and Pete: why does not work with " date => ?..? " instead of 'date >= ? and date <= ?'

Viorel Vladu
A: 
  >= i believe this will include the start_date in you query. ?..? will give BETWEEN start dates.. also valid:  ? BETWEEN ?.  
noob123