Reputation: 1090
I'm trying to give the user an option to search on a timescale. I am wanting a drop down menu to display options in a drop down menu like this:
Search from: 3 days ago, 1 week ago, 1 month ago, 6 months ago, 1 year. ect.
I understand that I have to use DateTime.now.to_date - 3.days
so rails understands that I want to query 3 days ago, but I'm not to sure how I would go about making the user see the 3 days ago option as text in the drop down, but query DateTime.now.to_date - 3.days
Thanks
My search view looks like this at the moment:
<h1>Search</h1>
<% if @project_search.total_entries > 0 %>
<%= form_tag search_path, method: :get do %>
Client :
<%= select(@projects, :client, Project.all.map {|p| [p.client]}.uniq, :prompt => "-Any-", :selected => params[:client]) %></br>
Industry :
<%= select(@projects, :industry, Project.all.map {|p| [p.industry]}.uniq, :prompt => "-Any-", :selected => params[:industry]) %></br>
Role :
<%= select(@projects, :role, Project.all.map {|p| [p.role]}.uniq, :prompt => "-Any-", :selected => params[:role]) %></br>
Technologies :
<%= select(@projects, :tech, Project.all.map {|p| [p.tech]}.uniq, :prompt => "-Any-", :selected => params[:tech]) %></br>
Business Division :
<%= select(@projects, :business_div, Project.all.map {|p| [p.business_div]}.uniq, :prompt => "-Any-", :selected => params[:business_div]) %></br>
Project Owner :
<%= select(@projects, :project_owner, Project.all.map {|p| [p.project_owner]}.uniq, :prompt => "-Any-", :selected => params[:project_owner]) %></br>
Exception PM
<%= select(@projects, :exception_pm, Project.all.map {|p| [p.exception_pm]}.uniq, :prompt => "-Any-", :selected => params[:exception_pm]) %></br>
<%= select_tag "start_date", options_for_select({
"3 days ago" => 3.days, # = 259_200 sec.
"1 week ago" => 1.week, # = 604_800 sec.
"1 month ago" => 1.month, # = 2_592_000 sec.
"6 months ago" => 6.months, # = 15_552_000 sec.
"1 year ago" => 1.year, # = 31_557_600 sec.
}) %>
Project Dates between
<%#= text_field_tag("start_date") %>
and
<%= text_field_tag("end_date") %></br>
Status :
<%= select(@projects, :status, Project.all.map {|p| [p.status]}.uniq, :prompt => "-Any-", :selected => params[:status]) %></br>
Keywords :
<%= text_field_tag :keywords, params[:keywords] %></br>
<%= submit_tag "Search", name: nil %>
<% end %>
My model:
class Project < ActiveRecord::Base
attr_accessible :business_div, :client, :customer_benifits, :edited_date, :end_date, :entry_date, :exception_pm, :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary, :tech
validates_presence_of :business_div, :client, :customer_benifits, :end_date, :exception_pm, :financials, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary, :tech
def self.search(search_client, search_industry, search_role, search_tech, search_business_div, search_project_owner, search_exception_pm, search_status, search_start_date, search_end_date, search_keywords)
return scoped unless search_client.present? || search_industry.present? || search_role.present? || search_tech.present? || search_business_div.present? || search_project_owner.present? || search_exception_pm.present? || search_status.present? || search_start_date.present? || search_end_date.present? || search_keywords.present?
where(['client LIKE ? AND industry LIKE ? AND role LIKE ? AND tech LIKE ? AND business_div LIKE ? AND project_owner LIKE ? AND exception_pm LIKE ? AND status LIKE ? AND DATE(start_date) BETWEEN ? AND ? AND DATE(end_date) BETWEEN ? AND ? AND keywords LIKE ?',
"%#{search_client}%", "%#{search_industry}%" , "%#{search_role}%" , "%#{search_tech}%" , "%#{search_business_div}%" ,
"%#{search_project_owner}%" , "%#{search_exception_pm}%" , "%#{search_status}%",
search_start_date, search_end_date, search_start_date, search_end_date,"%#{search_keywords}%"
])
end
def self.paginated_for_index(projects_per_page, current_page)
paginate(:per_page => projects_per_page, :page => current_page)
end
end
Upvotes: 1
Views: 2260
Reputation: 34135
Use Natural Language processing powered by chronic gem written by github guys. Get range in human readable format from the user & then use chronic
to parse them into a fully valid date that ruby understands and can be passed as a param to Active Record for quering the database
here some examples:
1.9.3p194 :001 > require 'chronic'
=> true
1.9.3p194 :002 > Chronic.parse '3 days ago'
=> 2012-07-31 15:20:59 +0530
1.9.3p194 :003 > Chronic.parse '1 week ago'
=> 2012-07-27 15:22:15 +0530
1.9.3p194 :004 > Chronic.parse '1 month ago'
=> 2012-07-03 15:22:26 +0530
1.9.3p194 :005 > Chronic.parse '6 months ago'
=> 2012-02-03 15:23:25 +0530
1.9.3p194 :006 > Chronic.parse '1 year ago'
=> 2011-08-03 15:23:34 +0530
Now, you also get bit francy here and also do something like
1.9.3p194 :007 > Chronic.parse 'last night'
=> 2012-08-02 22:00:00 +0530
More examples are available in the README but since its pretty flexible, I would say you can also get creative while taking input from user. so instead of pre-determined values in select box(which you still can do), you can allow the user to select any arbitrary date. I understand this is not the traditional way but I think using NLP is quite cool! so try it
Upvotes: 1
Reputation: 114138
You could specify the time range in seconds:
<%= select_tag "ago", options_for_select({
"3 days ago" => 3.days, # = 259_200 sec.
"1 week ago" => 1.week, # = 604_800 sec.
"1 month ago" => 1.month, # = 2_592_000 sec.
"6 months ago" => 6.months, # = 15_552_000 sec.
"1 year ago" => 1.year, # = 31_557_600 sec.
}) %>
And use that value in your query:
Model.where("created_at >", Time.now - params[:ago])
Upvotes: 1