Eric Milford :: Web Developer & Food Advocate

SQL: Introducing Having

Posted by Eric Milford on May 07, 2010

Tagged with ruby on rails, technology

I was asked recently to write the SQL needed to define a class method named User.busy? that would return an array of User records with a post count greater than or equal to 2.

Let's assume we have two tables, users and posts, linked by the primary key users.id and the foreign key posts.user_id.

I knew high level that I would need a join between the two tables and some way to apply a where clause on the count of posts grouped by users. A quick bit of research introduced me to the group by plus having technique.

1 select users.* from users join posts on posts.user_id = users.id group by posts.user_id having count(*) >= 2

Ta da!

Read Full Post »

Ordinalized Dates w/ Ruby on Rails

Posted by Eric Milford on October 16, 2009

Tagged with ruby on rails

December 31st, 1980. It's a common enough date format that I'm surprised a "%o" format placeholder or similar isn't available for Ruby's strftime method.

1 >> d = DateTime.now
2 => Fri, 16 Oct 2009 15:11:49 -0400
3 
4 >> date.strftime('%B %o, %Y')
5 => "October o, 2009" # Uh oh
6 
7 >> date.strftime('%B %o, %Y')
8 => "October 16th, 2009" # I wish

The following line of code is what I've seen most often referenced as a solution. It's quick and effective, but the double call to date feels unnatural and not very Rails-like.

1 date.strftime("%B #{date.day.ordinalize}, %Y")

For the Ruby-only crowd, you might very well be stuck. As I mentioned above, Ruby's standard method for date formatting does not support an ordinal date. In Rails, however, the convention is to place the DATE_FORMATS inside of an initializer, config/initializer/time_formats.rb.

 1 ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(
 2    :datetime_military   => '%Y-%m-%d %H:%M',
 3    :datetime            => '%Y-%m-%d %I:%M%P',
 4    :ordinalize      => lambda { |time| time.strftime("%a %b #{time.day.ordinalize}") }
 5 )
 6 
 7 >> d = DateTime.now
 8 => Fri, 16 Oct 2009 15:11:49 -0400
 9 
10 >> d.to_s(:ordinalize)
11 => "Fri Oct 16th"

Read Full Post »