kgautreaux/blog

An ocean of noise

Finding by date range in Rails

It's actually very simple to search a model attribute for a date range ever since Rails 1.2 or so, but the api docs and even books like Agile Programming with Rails don't seem to mention it, at least not where it's easy for an idiot like me to find. That's surprising since that book is the reference for Rails programming. If you didn't know any better, and you needed to find a group of records from your database that were created during a certain date range, you might be tempted to write some code like this to accomplish your search. [rails] object = Model.find(:all, :conditions => "created_at < 2.months.ago && created_at > 1.month.ago") [/rails] That would be wrong, though. The correct way is actually more simple and allows rails to do the heavy SQL lifting for you. The secret is to use a custom find method created by Rails for you from your database schema, and to use ranges in your condition statement. Viva La Metaprogramming! [rails] object = Model.find_all_by_created_at(2.months.ago..1.month.ago) [/rails] Pretty easy if someone tells you how to do it, but it took me several hours of Googling to find. Hopefully this will save time for others. Notice that find_all_by_created_at dynamic find method provided by Rails is used. When you create a scaffold or migration to set up your database using ruby script/generate ... then created_at will be a datetime formatted column created automatically by Rails. If you have another column that is datetime formatted like "sales_date" or "signup_date" you can also search on them by substituting the appropriate find_all_by method. As usual with Ruby and Rails the correct way to do it is much easier than the way you first suspect. Update: It seems the syntax highlighter doesn't want to do it's job on the front page. If you click through to read the whole post it works. I don't have time to sort it out now.