Searching ActiveRecord by DateTime not working - ruby-on-rails-3

I asked a question regarding this yesterday, but it was muddled and didn't make sense, so I'm going to boil it down to the core issue.
I have an entries table. When a new record is saved, the entries_controller adds a time to the date column, which is recorded as a datetime. In the new method, I declare a new DateTime as so:
#entry.date = DateTime.new( params[:year].to_i, params[:month].to_i, params[:day].to_i )
I then include it as a hidden field with formtastic:
<%= f.input :date, :as => :hidden %>
Once the entry is saved to the database, the date field looks like 2011-02-10 00:00:00. Everything is working as planned so far, but when I try to retrieve that entry by querying against the date field, I get nil.
I've tried:
search_date = DateTime.new(2011,2,10)
Entry.find_by_date(search_date)
=> nil
I've even tried to search by string, which doesn't make sense since it's a datetime field.
search_time = '2010-02-10 00:00:00'
Entry.find_by_date(search_date)
=> nil
What am I doing wrong here? Why can't I retrieve the record by date?

Would this work for you?
Entry.where("date = #{search_date}")

I just tested this in Rails 3.0.4, mysql2 0.2.6 and
Entry.find_by_date(DateTime.new(2011,2,10))
works.
Having said that, why are you using a datetime column to save a date? Other than it just being a bad idea, you possibly could be running into some kind of timezone issues based on your rails and sql settings. Some automatic timezone conversion could explain the behaviour you are observing but that's just a guess. Please check the development server logs to see if rails is indeed generating the query you wish it to generate.

Related

simple_form date not working after the 12th of each month

Has anyone run into this problem? I have a User object and a simple_form which asks for the User's birthday.
<%= f.input :birthday, as: :date, start_year: Date.today.year - 70,
end_year: Date.today.year, order: [:month, :day, :year], label: false %>
Any date I pick I can only pick a day up to the 12th of each month. If I pick 13th or higher simple_form says "Please enter a valid date". Very strange.
I got this code from https://github.com/plataformatec/simple_form and all it says about this code is "SimpleForm accepts same options as their corresponding input type helper in Rails". Does anyone know where the corresponding input type helper in Rails is documented?
I would guess that you've confused :day and :month somewhere.
Or maybe, put differently, you want to use the American format and instead you're using the european format (or the reverse). Not sure it will help, but see this link:
How can I use US-style dates in Rails using Ruby 1.9?

Rails field "can't be blank", even though it's not blank

I'm using Rails 3 and failing to submit a form because one of the fields fails to pass validates_presence_of. My model is called dinner, and the field, which is used in conjunction with a datepicker, is called date.
views/dinners/new.html.erb:
<%= f.text_field :date, id: "datepicker" %>
models/dinner.rb:
attr_accessible :date
validates_presence_of :date
dinners_controller.rb:
def create
#dinner = Dinner.new params[:dinner]
if #dinner.save
flash[:notice] = "Dinner created successfully."
redirect_to controller: 'dinners'
else
flash.now[:alert] = #dinner.errors.full_messages.join("<br>").html_safe
render action: "new"
end
end
Whenever I fill out all of the fields, including date, I get the error "Date can't be blank", even though it is not blank. What's going on here?
I've found the answer.
My date column was of type date, and before validation Rails ran .to_date on it. Unfortunately, the datepicker that I use creates dates in the American mm/dd/yy format, which Rails can't handle, so .to_date returned nil. That's why the date failed validation: because it really was nil, even though the POST request was fine.
I chose the easy solution and changed the default date of datepicker, as shown here.
Note: For my version of datepicker, I had to use format instead of dateFormat, and also had to use yyyy-mm-dd instead of yy-mm-dd because Rails String#to_date thinks that the year "13" is literally '0013' and not '2013'.

Datepicker ui with formtastic, rails 3.1

I use rails 3.1, formtastic 2.0.2 and datepicker ui
I made datepicker_input.rb:
class DatepickerInput < Formtastic::Inputs::StringInput
include Formtastic::Inputs::Base
def input_html_options
super.merge(:class => "datepicker")
end
end
In application.js I wrote:
$('input.datepicker').datepicker()
I use it in my form like :as => :datepicker. I see calendar, pick date and everything is fine except for it doesn't fill column in my model. The only thing that I noticed is that when I fill first date and then all the other fields - it works. When date field is the last - it doesn't work. There is no errors, params[:model_name][:date_field] is not empty just nil in place of date that I chose.
Error was in date format - database just couldn't take format that returned datepicker.

Rails ActiveRecord Find with Date

I'm having a hard time figuring this out but how do I tell my finder statement to ignore the time of the Datetime field in the db?
def trips_leaving_in_two_weeks
Trip.find(:all, :conditions => ["depart_date = ?", 2.weeks.from_now.to_date])
end
I want depart_date to come back as just a date but it keeps returning the time as well and causing this equality not to work. Is there someway to just compare against the dates? Thanks
Edit
Here's the code I'm using now that works:
Trip.find(:all, :conditions => ["DATE(depart_date) = ?", 2.weeks.from_now.to_date])
Not sure which DB you're using but does this work?
"depart_date = DATE(?)"
I would use this approach:
Rails 3.x
Trip.where(
:depart_date => 2.weeks.from_now.beginning_of_day..2.weeks.from_now.end_of_day
)
Rails 2.x
Trip.all(
:conditions => {
:depart_date => 2.weeks.from_now.beginning_of_day..2.weeks.from_now.end_of_day
})
If you index the depart_date column this solution will be efficient as the query uses the index. This solution is DB neutral.
When calculated fields are used in a where clause, the performance degrades(unless there is a special index).

Do Rails 3 Active Record dynamic find_or_create finder methods have some undocumented inconsistencies?

Apologies for the long title, but this is bothering me. I'm new to Rails, so this is my first project. Rails 3.0.3.
In my model, a User may or may not have read many Entries; this is tracked in a model called ReadEntries. This many-to-one relationship is properly defined in the code, I think.
User.rb:
has_many :read_entries
Entry.rb:
has_many :read_entries
ReadEntry.rb:
belongs_to :entry
belongs_to :user
This table has to be populated at some point. If I try to do this:
user.read_entries.find_or_create_by_entry_id(entry.id, :read => false)
I get the error Unknown key(s): read. Leave out trying to set :read, and it works.
However, if I create the same row with this, it works:
ReadEntry.find_or_create_by_entry_id_and_user_id(entry.id, user.id, :read => false)
Logically, these methods should be identical, right? Thanks.
I've also had weird experiences with find_or_create. I would love it if it worked, but it seems inconsistent.
I'm currently having the same issue as you, and I think it may be due to calling find_or_create on an association as opposed to the model directly. Here's my example:
permission_assignments.find_or_create_by_role_id(:role_id => role_id, :is_allowed => false)
This works to create the assignment, except the "is_allowed" field gets set to it's default of "true". This code works for me (in the Permission model, hence the self reference)
PermissionAssignment.find_or_create_by_permission_id_and_role_id(:permission_id => self.id, :role_id => role_id, :is_allowed => false)
It's more verbose, unfortunately, but it works. The only problem that I still notice is that the object that is returned has no id assigned (the record does get created in the database, however, but if I wanted to update any more attributes I wouldn't be able to without the id). Don't know if that's a separate issue or not.
Rails 3.0.4 here with Postgres 8.4
You cannot pass in other fields like that as Rails will assume they are options for the find. Instead, you will need to make your method call longer:
user.read_entries.find_or_create_by_entry_id_and_read(entry.id, false)
Or alternatively use a shorter, custom syntax for that.
For your final example, my thoughts are that Rails will take the second argument and use that as options. Other than that, I am not sure.