Rails SQLException syntax errors (Model.where('date > ? AND date < ?, min, max) - sql

I'm trying to look up the 'events' that fall between two datetimes.
if (params[:timeMin].present? and params[:timeMax].present?)
#events = Event.where('date > ? AND date < ?', params[:timeMin], params[:timeMax])
I keep getting a similar error and I can't figure out how to fix it.
SQLite3::SQLException: near ",": syntax error: SELECT "events".* FROM "events" WHERE (date > '---
- (1i)
- ''2014''
','---
- (2i)
- ''1''
','---
- (3i)
- ''8''
','---
- (4i)
- ''14''
','---
- (5i)
- ''36''
' AND date < '---
- (1i)
- ''2014''
','---
- (2i)
- ''1''
','---
- (3i)
- ''13''
','---
- (4i)
- ''14''
','---
- (5i)
- ''36''
') ORDER BY events.created_at DESC
This is the line causing the issue in the view
<% #events.each do |event| %>
Thanks
Requested info
index.html.erb
<%= form_tag events_path, :method => :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= datetime_select :timeMin, params[:timeMin] %>
<%= datetime_select :timeMax, params[:timeMax] %>
<%= submit_tag "Search Near", :name => nil %>
</p>
<% end %>
Using solution from #CDub
log when make request with dates that should return 2 (all) events -> none are returned (empty list)
Started GET "/events?utf8=%E2%9C%93&search=&timeMin%5B%281i%29%5D=2014&timeMin%5B%282i%29%5D=1&timeMin%5B%283i%29%5D=7&timeMin%5B%284i%29%5D=15&timeMin%5B%285i%29%5D=13&timeMax%5B%281i%29%5D=2014&timeMax%5B%282i%29%5D=1&timeMax%5B%283i%29%5D=13&timeMax%5B%284i%29%5D=15&timeMax%5B%285i%29%5D=13" for 127.0.0.1 at 2014-01-13 18:13:45 -0800
Processing by EventsController#index as HTML
Parameters: {"utf8"=>"✓", "search"=>"", "timeMin"=>{"(1i)"=>"2014", "(2i)"=>"1", "(3i)"=>"7", "(4i)"=>"15", "(5i)"=>"13"}, "timeMax"=>{"(1i)"=>"2014", "(2i)"=>"1", "(3i)"=>"13", "(4i)"=>"15", "(5i)"=>"13"}}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'BVjMjs3hJ1HV6udJzEg4-g' LIMIT 1
Event Load (0.1ms) SELECT "events".* FROM "events" WHERE (date > '2014-1-7 15:13:' AND date < '2014-1-13 15:13:') ORDER BY events.created_at DESC
Rendered events/index.html.erb within layouts/application (9.1ms)
Rendered layouts/_shim.html.erb (0.0ms)
Rendered layouts/_header.html.erb (1.1ms)
Rendered layouts/_footer.html.erb (0.2ms)
Completed 200 OK in 53ms (Views: 52.1ms | ActiveRecord: 0.3ms)

You're returning a datetime_select hash which will need to be parsed into a string. One way of doing so is to do the following:
min_hash = params[:timeMin]
max_hash = params[:timeMax]
min_time_string = "#{min_hash['(1i)']}-#{min_hash['(2i)']}-#{min_hash['(3i)']} #{min_hash['(4i)']}:#{min_hash['(5i)']}:#{min_hash['(6i)']}"
max_time_string = "#{max_hash['(1i)']}-#{max_hash['(2i)']}-#{max_hash['(3i)']} #{max_hash['(4i)']}:#{max_hash['(5i)']}:#{max_hash['(6i)']}"
After this parsing, this should work:
#events = Event.where('date > ? AND date < ?', min_time_string, max_time_string)

Related

Rails form - search engine

I try to create simple search engine but I meet some problmes. I have several search_field in my form and if either is empty should returns all objects. Otherwise when it has any content it should be selected by that content. Below is my sample form:
<%= form_for :product, url: products_path, method: :get do |form| %>
<%= form.search_field :brand %>
<%= form.search_field :model %>
<%= form.search_field :price_from %>
<%= form.search_field :price_to %>
<%= form.submit 'Submit' %>
<% end %>
my model method:
def self.search(search)
where(brand: search[:brand]).where(model: search[:model]).where("price >= ?", search[:price_from]).where("price <= ?", search[:price_to])
end
But the above piece of code is wrong because if I leave some field empty it is treated directly as empty string instead of ignore this field and final result is not correct.
Summary this form should work similarly to filter on online store
You'd could do something like this
def self.search(search)
results = all
results = results.where(brand: search[:brand]) if search[:brand]
results = results.where(model: search[:model]) if search[:model]
results = results.where("price >= ?", search[:price_from]) if search[:price_from]
results = results.where("price <= ?", search[:price_to]) if search[:price_to]
return results
end
Good luck.

Thinking Sphinx searching search across all models

i've implemented search for induvidual models and it works.
Now i have my home page which has a form that has fields from several models of my application but searching one field at a time doesn't yield any result on the home page although i can see the query....(searching for tv_show name)
Parameters: {"utf8"=>"✓", "name"=>"count", "broadcast_date_from"=>"", "broadcast_date_to"=>"", "gender"=>"", "organization_id"=>"", "position_id"=>"", "alignment"=>"", "commit"=>"Generate"}
Sphinx Query (1.0ms) SELECT * FROM `episode_core`, `organization_core`, `person_core`, `position_core`, `profession_core`, `segment_core`, `tv_show_core` WHERE MATCH('*count*') AND `sphinx_deleted` = 0 ORDER BY `last_name` ASC, first_name ASC LIMIT 0, 20
Sphinx Found 0 results
Rendered home/index.html.erb within layouts/home (3.0ms)
Completed 200 OK in 13ms (Views: 12.9ms | ActiveRecord: 0.0ms)
when search the model tv_show i have a result.
Parameters: {"utf8"=>"✓", "name"=>"count", "channel"=>"", "starting_time"=>"", "ending_time"=>"", "commit"=>"Search"}
Sphinx Query (0.9ms) SELECT * FROM `tv_show_core` WHERE MATCH('*count*') AND `sphinx_deleted` = 0 ORDER BY `tv_name` ASC LIMIT 0, 20
Sphinx Found 2 results
TvShow Load (0.5ms) SELECT "tv_shows".* FROM "tv_shows" WHERE "tv_shows"."id" IN (9, 4)
Rendered tv_shows/index.html.erb within layouts/application (7.5ms)
Rendered tv_shows/_search.html.erb (0.9ms)
Completed 200 OK in 68ms (Views: 66.7ms | ActiveRecord: 0.5ms)
So why is there a difference?
global search no result
#results = ThinkingSphinx.search.search "#{params[:name]} ",
:star => /[\w#:]+/u,
:order => 'last_name ASC, first_name ASC',
:page => params[:page],
:per_page => 20
model search return results
#tv_shows = TvShow.search "#{params[:name]} #{params[:channel]} ",
:star => /[\w#:]+/u,
:order => 'tv_name ASC',
:page => params[:page],
:per_page => 20
UPDATE
ok removing the :order => 'last_name ASC, first_name ASC', get me somewhere.
Have another question
how do you make it query a specific model depending on the field used in the form?
Parameters: {"utf8"=>"✓", "name"=>"count", "broadcast_date_from"=>"", "broadcast_date_to"=>"", "gender"=>"", "organization_id"=>"", "position_id"=>"", "alignment"=>"", "commit"=>"Generate"}
Profession Load (0.9ms) SELECT "professions".* FROM "professions" ORDER BY name
Organization Load (2.5ms) SELECT "organizations".* FROM "organizations" ORDER BY name
Position Load (2.0ms) SELECT "positions".* FROM "positions" ORDER BY name
Sphinx Query (1.7ms) SELECT * FROM `episode_core`, `episode_delta`, `organization_core`, `organization_delta`, `person_core`, `person_delta`, `position_core`, `position_delta`, `profession_core`, `profession_delta`, `segment_core`, `segment_delta`, `tv_show_core`, `tv_show_delta` WHERE MATCH('*count*') AND `sphinx_deleted` = 0 LIMIT 0, 20
Sphinx Found 4 results
Organization Load (0.5ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."id" IN (109)
Position Load (0.4ms) SELECT "positions".* FROM "positions" WHERE "positions"."id" IN (164)
TvShow Load (0.4ms) SELECT "tv_shows".* FROM "tv_shows" WHERE "tv_shows"."id" IN (4, 9)
Here i am just using the tv_show field which refer to the TvShow model.
Adding a conditon is not helping....:condition => {:tv_name => params[:name]}
any insight appreciated.
Response(just in case)
Needed to add in the global search view :
<% for result in #results %>
<% if result.class.name == "Organization" %>
<%= render :partial => "organizations/result", :locals => { :result => result } %>
<% elsif result.class.name == "Position" %>
<%= render :partial => "positions/result", :locals => { :result => result } %>
<% elsif result.class.name == "TvShow" %>
<%= render :partial => "tv_shows/result", :locals => { :result => result } %>
<% end %>
<% end %>
and create partial ( _result.html.erb ) for each model in view folder to print the different fields (The partials are optional).

Rails mailer template calculation

I am new to rails and am writing a daily report email template.
I am Outputting unique visitors, and calculating the difference between the 2 and displaying that as well with a + or - sign depending on if its positive or negative.
Is there a better way to do this? Should I not be doing math inside the view?
Unique Visitors: <%= number_with_delimiter(#stats["unique_visitors"]) %>
<% uniquediff = #stats["unique_visitors"] - #stats["unique_visitors_yesterday"] %>
(<% if uniquediff > 0 then %> + <% else %> - <% end %> <%= uniquediff %>)<br />
Try:
("+" if uniquediff>=0)+uniquediff.to_s
.to_s turns uniquediff to a string, and the ("+" if uniquediff>=0) bit evaluates to "+" if uniquediff is greater than or equal to zero, and nothing otherwise.. and you will already have a "-" if it is negative.
=]
How about this:
<% unique_diff = #stats['unique_visitors'] - #stats['unique_visitors_yesterday'] %>
<%= "Unique Visitors: #{number_with_delimiter(#stats['unique_visitors'])} #{'+' if unique_diff > 0}#{unique_diff}" %><br/>
It's recommended to do logical stuff in HELPER(and it's what a helper should do).
# In helper, eg. application_helper.rb
def unique_diff(stats)
unique_diff = stats['unique_visitors'] - stats['unique_visitors_yesterday']
(unique_diff > 0) ? "+#{unique_diff}" : "#{unique_diff}"
end
# In view
Unique Visitors Diff: <%= unique_diff #stat %>

Month pagination with kaminari

I want to paginate posts by month so I added following scope in Post model
class Post
include Mongoid::Document
include Mongoid::Timestamps
scope :by_month, lambda {|end_date| Post.order_by(:created_at => :asc).where(:created_at.gte => (end_date.to_date.beginning_of_month), :created_at.lte => (end_date.to_date))}
end
In my controller I put
def show
#posts = Post.by_month(Time.now).page(params[:page]).per(20)
end
In view
<%= paginate #posts, :theme => 'month_theme' %>
<%= render #posts %>
Problems:
pagination is not working by month, I want to show all result of a month in a page, replacing params[:page] by params[:month]=2 or params[:month]=Feb
How do I view 'August 2011' instead of 1,2
Loop month and year like when you goto previous while in 'Jan 2011' it will goto 'Dec 2010'
I suppose this is not really a matter of pagination. Dealing with the params[:month] value for the query is something different from the page offset switching. You might not need a pagination library for that.
How about simply creating those links like this?
controller:
#posts = Post.by_month(Time.parse(params[:month]) || Time.now)
view:
<% Post.only(:created_at).map {|p| p.created_at.to_date.beginning_of_month}.uniq.sort.each do |m| -%>
<%= link_to_unless_current m, :month => m %>
<% end -%>
Of course you can combine this query with normal pagination if needed. But the pagination links should not be mixed with the month links in that case.

Group and count in Rails

I have this bit of code and I get an empty object.
#results = PollRoles.find(
:all,
:select => 'option_id, count(*) count',
:group => 'option_id',
:conditions => ["poll_id = ?", #poll.id])
Is this the correct way of writing the query? I want a collection of records that have an option id and the number of times that option id is found in the PollRoles model.
EDIT: This is how I''m iterating through the results:
<% #results.each do |result| %>
<% #option = Option.find_by_id(result.option_id) %>
<%= #option.question %> <%= result.count %>
<% end %>
What do you get with this:
PollRoles.find(:all,:conditions=>["poll_id = ?",#poll.id]).collect{|p| p.option_id}
You want to use this function to do things like this
PollRoles.count(:all, :group => 'option_id') should return a hash mapping every option_id with the number of records that matched it.