ActiveRecord .count and .length are different when .group

When you do ActiveRecord query such as

the_list = Phone.joins(:beeps).where(["(beeps.store_id = ?) AND (userphone LIKE ?)",, "%#{submitted_phone}"])

the_list.count and the_list.length both return the integer # of records found, although .count results in an additional query against the database.

However, if you add a .group(:userphone), then the_list.count returns a hash of unique userphones => counts, while the_list.length returns the integer number of unique userphone found.

Setting the default time zone for a Heroku app

For Rails apps running on Heroku, by default and some_time.localtime will display in UTC. If you’d like to assign a timezone to your app, you can set the TZ config variable to a time zone (which must be in the tz database timezone format).

Personally I despise the tz database format, because it requires you to guess WHICH city is chosen to represent that time zone (for Pacific, it’s Los_Angeles, not Seattle, not San_Francisco). But that’s what Heroku uses, so to set your app to Pacific you simply run:

heroku config:add TZ="America/Los_Angeles"

The allowed options are listed on the page linked above.

Using those fantastic Apple Cube USB Speakers with a MacBook Pro under Lion

My favorite desktop speakers are still the Harmon Kardon speakers that came with my old G4 Cube.

The newer Apple USB audio drivers (at least, as of Lion) do not turn on the speakers, but there is an easy fix described at the end of this thread on Apple support. (Ignore the earlier posts about modifying the circuit board, it’s not required.)

In case the thread goes away, you download the old version of AppleUSBAudio.kext thoughtfully posted online by a forum poster here.

Then find and download Kext Wizard (I used v3.7.10) and use it to Install the older AppleUSBAudio.kext file.

As noted in the thread, it can sometimes be a little squirrelly when changing volume using the volume keys on a keyboard, sometimes a quick unplug/plugin is required. But the sound is sweet and the look is still classic Apple-cool.

Finding a decent editor for Rails

We’ve used BBedit since 2003 (version 7). But BBedit, even version 10, has some shortcomings for Rails… no parenthesis matching/highlighting, no HAML support (the one github repo we found doesn’t work with Lion or BBedit 10)

We used Komodo Edit for nearly a year, but both versions 6 and 7 began to crash frequently (hourly) on one of our larger projects.

We tried TextMate, and cannot fathom why so many Rails developers still use it. Even saw a bug where it renamed the wrong file after we did a save-as to a different folder, then renamed the original file (it renamed the new file instead).

So far, we’re liking Sublime Text 2. Highlights so far:

  • You can click on a file in the project pane and browse it WITHOUT cluttering up the “open files” on the tabs bar, a feature I don’t recall seeing anywhere else. (If you make an edit, it gets added to the tab bar. If you double-click it, it gets added to the tab bar. But single click and you can simply browse it and it disappears from the editor window when you select a new file. That is elegant.
  • The ONLY settings we had to tweak at startup was View > Indentation > Tab width:2 spaces
  • Out of the box it highlighted HAML syntax, HAML block comment/uncomment, and HAML snippets like ft creating a HAML form_tag
  • Bracket matching, vertical indentation guides.
  • I also like that their evaluation period isn’t fixed, and they don’t have an annoying nag screen (at least, not at first)

Rails apps can send from multiple SMTP accounts

One of our Rails apps send both bulk email blasts, and also onesey-twosey non-bulk emails such as welcome emails or follow-up emails.

We wanted the non-bulk emails to actually come from one of our monitored customer service accounts, while still using Sendgrid for our bulk email blasts.

When we searched, we found a lot of schemes for configuring Rails to permit multiple SMTP accounts, however they seemed overly complex.

Here’s how we solved it very simply:

  • In addition to our existing user_mailer.rb, we created a new non_bulk_mailer.rb.
  • We removed the ‘normal’ SMTP configuration from environment.rb
  • At the top of each of our xxxx_mailer.rb class definition files we added self.smtp_settings = with the appropriate smtp configuration hash
  • We moved the ‘personal’ email handlers out of the original user_mailer.rb and into non_bulk_mailer.rb (and moved the associated views as well)

So our mailer classes each look like:

class NonBulkMailer < ActionMailer::Base
self.smtp_settings = {
:address => ENV['MF_NONBULK_ADDRESS'],
:port => ENV['NONBULK_PORT'], 
:domain => ENV['NONBULK_DOMAIN'], 
:user_name => ENV['NONBULK_USER'], 
:password => ENV['NONBULK_PWD'] } ...

Note we keep the passwords etc in environment variables, so each environment (local, Heroku staging, Heroku production) can have their own settngs, plus all passwords are kept out of our git repository.

Example of an ethical annual credit card renewal: kudos to Vimeo

We joined Vimeo for video hosting 11 months ago, are on an annual-renewal plan.

These days, the typical ‘reminder’ is sent by Web Company X only AFTER they have charged your card for another year – they place the onus of remembering renewal anniversaries on you.

So it was refreshing to get this notice in our email this morning, reminding us a month ahead of time of the impending charge:

Kudos to Vimeo for responsible billing practices that do not rely upon users forgetting about their account in order to rack up extra subscription revenue.

My favorite Ruby thing this week: when *my_array

This week we added a feature where our texting club customers can define their own aliases for the JOIN keyword, so they can track and measure which advertising is attracting people to JOIN. (For example a receipt might say “Text JOIN to…” while a sign in a bus might say “Text SNOWBUNNY to ….”)

In Ruby, the basic use of case / when is something like:

case keyword
when "KEYWORD1"
  # do something
when "KEYWORD2"
  # do something else

In this case, the when needs to evaluate run-time data, not compile-time data. In Ruby it is trivially simply to implement run-time comparison arguments for a case – when statement by using an array name as the argument to the when clause.

The solution with Ruby is trivially simple: use when *array_name

join_aliases = ("JOIN " + myaccount.join_aliases.to_s).split(" ")
  # sets join_aliases = ["JOIN", "SNOWBUNNY", "SNOW"]
case keyword
when *join_aliases
  # do JOIN stuff