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 ?)", @store.id, "%#{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 Time.now 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.

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.

Side effect in simple_form can break phone number input on iphone

We use (and love) the simple_form 2.0 gem in rails 3 apps, but discovered one undesirable side effect of some of the automagic mapping they do.

Problem: If you have a field on your webpage named “phone” and your app is letting people input their phone number as a flexible string such as “Office (555) 555-5555 ext 123″ the user is screwed on an iphone because it will be a ‘phone-keys-only keyboard’ with NO way to type alpha chars.

Reason: The reason is that the simple_form DSL adds the class ‘tel’ to the input field if the field name is named ‘phone’, and on the iphone that prevents any alpha input.

Workaround: The fix is simple, add “:as => :string” to your “f.input :phone” statement and the simple_form gem will assign a class ‘string’ instead of ‘tel’.

Getting ActiveAdmin and web-app-themes to work with Rail 3.1 at Heroku

(If all you care about is getting Activeadmin to work at Heroku, skip to step 4. If you want to know how to fix scaffolding to the normal rails default after installing ActiveAdmin, skip to step 7.)

Rails 3.1 at Heroku is not quite an “out of the box” deployment.

Part 1. To get started, I recommend http://blog.bryanbibat.net/2011/09/24/starting-a-professional-rails-3-1-app-with-web-app-theme-devise-and-kaminari/

Part 2. If you used the ‘default’ theme for web-app-theme, you need to add a few styles that all the themes except ‘default’ have. Add the following to the end of app/assets/stylesheets/web-app-theme.css:

/* Write here your css for overriding the theme's rules */<br></br>
.small { font-size:.8em; }<br></br>
.gray { color:#999999; }<br></br>
.hightlight { background-color:#FFFFAA; }<br></br>

Since I’m using rails 3.1 I also had to override the stylesheet to use web fonts. So I moved the /app/assets/web-app-theme/theme/default/fonts folder to /public/fonts and copied the @font-face definitions from the default/style.css to app/assets/stylesheets/web-app-theme.css and simply added a “/” in front of the font paths:

@font-face {
  font-family: "MuseoSans500";
  src: url("/fonts/museosans_500-webfont.eot");
  src: local("☺"), url("/fonts/XXXXX.woff") format("woff"), url("/fonts/XXXX.ttf") format("truetype"), url("/fonts/XXXX-webfont.svg#webfontxx") format("svg");
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: "MuseoSans500Italic";
  src: url("/fonts/XXXX.eot");
  src: local("☺"), url("/fonts/XXXX.woff") format("woff"), url("/fonts/XXXX.ttf") format("truetype"), url("/fonts/XXXX.svg#webfontxxf") format("svg");
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: "Museo700";
  src: url("/fonts/XXXX.eot");
  src: local("☺"), url("/fonts/XXXX.woff") format("woff"), url("/fonts/XXXXttf") format("truetype"), url("/fonts/XXXX.svg#webfontxx") format("svg");
  font-weight: normal;
  font-style: normal;
}

Part 3. Add ActiveAdmin, per the excellent tutorial at http://net.tutsplus.com/tutorials/ruby/create-beautiful-administration-interfaces-with-active-admin

There is also a very helpful RailsCast for customizing ActiveAdmin at http://railscasts.com/episodes/284-active-admin

Part 4. Add a fix for Devise at https://github.com/plataformatec/devise/commit/96f55a7ac7a61effd03a7f43dbbdfb6af8894579#diff-1 specifically add to config/application.rb
config.assets.initialize_on_precompile = false<br></br>
I also added

  # Enable the asset pipeline<br></br>
  config.assets.enabled = true<br></br>

Part 5. Add a fix for ActiveAdmin at https://github.com/gregbell/active_admin/issues/474, specifically, add this to the top of your routes.rb file:

# The ActiveAdmin routes cause Rails to set up a connection to the
# production database, which isn't available during
# assets:precompile on Heroku, so the following unless block skips
# setting up these routes only when rake assets:precompile is
# being run.<br></br>
#
# Could be a problem if the assets needed these to be loaded to
# compile properly; pretty sure they don't.
break if ARGV.join.include? 'assets:precompile'

Part 6. Heroku was still showing a SASS error after I pushed, which was fixed by moving the sass-rails gen OUT of the assets group (eg, move it amongst the regular gems) in the Gemfile, per http://ygamretuta.me/2011/10/02/setting-up-active-admin-on-heroku-with-rails-3-1-and-cedar/

Part 7. FIXING RAILS SCAFFOLDING. After installing ActiveAdmin, the ‘rails g scaffold’ command no longer works normally. ActiveAdmin adds the inherit_resources gem, which has the side effect of replacing the normal “rails generate scaffold” process to one which by default is based upon inherit_resources. If you want to run the ‘normal’ rails g scaffold command you need to add -c=scaffold_controller at the end of the command line, for example
rails g scaffold Foo name:string -c=scaffold_controller