Error installing Ruby 2.0.0-p0 with Homebrew, OpenSSL 1.0.1e errors

This has been driving me crazy all evening. It turns out when you use Homebrew, the installation directories for OpenSSL and Readline libraries are different. Fortunately, there’s a compilation override as mentioned on the ruby-build Issues page:

RUBY_CONFIGURE_OPTS=”–with-openssl-dir=`brew –prefix openssl` –with-readline-dir=`brew –prefix readline`” rbenv install 2.0.0-p0

You can of course change which Ruby version to install, like 1.9.3-p392.

Stubbing Devise helpers to get RSpec to pass

I have literally been bashing my head into the wall this past week trying to figure out how to get RSpec view tests to pass when using Devise. I finally figured it out after a lot of trial and error because there is a particular combination of things you have to have in place to make things work.

First, the what: I added some navigation to a menu bar that only shows up if the user is logged in. It was just:

<nav>
  <% if user_logged_in? %>
    <%= link_to ...blah... %>
  <% end %>
</nav>

The trouble is, I kept getting this error:

Failure/Error: render
ActionView::Template::Error:
  undefined method `authenticate' for nil:NilClass

The first problem was figuring out why Devise’s helpers weren’t being loaded. According to the Devise documentation you should create a spec/support/devise.rb file like:

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
end

But what about running view tests? The missing line is:

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
  config.include Devise::TestHelpers, :type => :view
end

Great! But that only solves the missing helpers. What about getting current_user to actually return a user? I tried all sorts of things and spent days searching for the answer and it comes down to stubbing out the helpers … but which object? The answer is on the view itself:

module ApplicationRspecHelpers
  def stub_user
    @user = double('user')
    @user.stub(:id => 100)
    view.stub(:user_signed_in? => true)
    view.stub(:current_user => @user)
  end
end

That works exactly as I want it. So now I can write my view tests like:

require 'spec_helper'

describe 'layouts/application' do
  include ApplicationRspecHelpers

  describe 'authentication nav' do
    context 'when authenticated' do
      it 'should have Log Out' do
        stub_user
        render
        rendered.should have_selector('nav a', text: 'Log Out')
      end
    end
  end
end

Hide the iPhone address bar (navigation bar) without appearing to move the page

The popular trick most people apparently do to remove that iPhone address bar in mobile Safari is to scroll the window up by 1 pixel:

window.scrollTo(0, 1);

My problem with this is it shifts the canvas up thereby losing 1 pixel. It turns out you can specify a fraction of a pixel and the trick works just fine still:

Note: I added a 100ms delay to it because it made it work better. I tried listening to the window “load” event it just wasn’t as reliable.

Setup Rails gem Devise to work with Amazon’s Simple Email Service (SES)

This post is mostly for me to remember how to do this. :)

It turns out that getting Devise (or the built-in mailer for that matter) to send email through Amazon Web Services’ (AWS) Simple Email Service (SES) is stupid easy. Most of the work is just getting SES set up properly. After that:

1. Verify some email addresses

  • If you just set up SES you are probably still in sandbox mode. You need to add new recipients on the Verified Senders dashboard first.

2. Generate your SES SMTP Credentials

  • You must generate a new SMTP User and SMTP Password to connect ActionMailer to AWS SES. These are NOT your AWS login credentials!
  • Go to the SMTP Settings dashboard.
  • Click the button “Create My SMTP Credentials”.
  • Copy the information out—it will not be displayed again!

3. Edit your ActionMailer settings in the production.rb file

That should do it! Send yourself a test message.

Remember: you can only send to verified email addresses while in Sandbox Mode. You must request Production Mode access to send to any unverified email address. Otherwise you will probably see the Rails log error: Net::SMTPFatalError (554 Message rejected: Email address is not verified.)

Setup Amazon’s (AWS) Simple Email Service (SES) + DKIM with DreamHost’s DNS

This is mostly a note to myself on how to do this. :)

Amazon’s Simple Email Service (SES) seems pretty easy to use but working with the DreamHost DNS management proved slightly tricky because of the large amount of steps and the order of them. Getting the DNS values right was also not completely obvious. Here’s my recipe:

1. Register a Domain

  • Log into your DreamHost Panel
  • Add a domain (Domains -> Registrations)

2. Change the Domain to DNS-only

  • Click the Edit link for your domain (Domains -> Manage Domains -> Edit)
  • Scroll all the way down to the DNS Only section
  • Choose that

3. Turn on Amazon SES

  • Create your Amazon Web Services (AWS) account
  • Go to the console page
  • Click SES to get to your SES dashboard
  • Click Verify New Sender
  • Click Verify a New Email Address
  • Wait until your new email address shows up in the Email Addresses list (or hit Refresh)
  • Click on the new email address to get its Details, you should see Status: pending verification

4. Verify Your Email Address

  • You should have gotten an email with the verification link in it: click it
  • Go back to the SES dashboard and click on the new email

5. Update DNS custom records on DreamHost

  • Return to your DreamHost Panel
  • Click Domains -> Manage Domains
  • Click the DNS link under your domain
  • Scroll down to the “Add a custom DNS record to YOURDOMAIN.com” section
  • Add a TXT record with the full value:
    • Notice: SES might recommend a text record of _amazonses.YOURDOMAIN.com. Do not paste this full value in! You must remove the “.YOURDOMAIN.com” part. That’s right, just enter: _amazonses
  • You might also want to add DKIM to your domain as well.
    • Click the “copy record” link to see the full name and value.
    • Notice: Again, SES might recommend a CNAME record that looks like abcdefghijklmnop1234567890._domainkey.YOURDOMAIN.comYou need to remove “.YOURDOMAIN.com” for DreamHost.

6. Wait…!

  • It takes a while for the DNS records to propagate. You will also get an email notification that says the sender is verified and the DKIM verification is complete.

 

Lessons learned: Ruby’s local variable scoping behavior

I was looking over some code that I thought should have generated an error:

def something
  # ... blah blah blah

  if some_condition_never_run
    foobar = some_method_making_a_value
  else

  call_other_method foobar  
end

In this case I thought foobar would have been undefined at the point where call_other_method() is run, but no! The value nil was being passed in. I somehow expected instead the error: undefined local variable or method `foobar’. Why didn’t this make an exception? Scoping.

Check this:

Even though the stuff in the if block isn’t executed the fact is that foobar is assigned at least once in that localized scope. Therefore when Ruby runs call_other_method() it knows it’s a variable (not a method) and can safely return nil. In the above example, function c‘s proc creates that local variable context within c() and so c‘s foobar doesn’t know about the proc‘s foobar.

It makes sense when you think about it but I still find it awkward.

See also:

Getting output from Rails template helpers, plus blocks

I had something I was doing repetitively in an ERb template today and I figured I’d DRY it up by making a helper. Specifically, I was trying to output some given HTML unless a condition was met that should generate a hidden field instead—this case calls for handcrafted HTML generation.

I was doing things like:

<% ignore_these_fields = ['foo', 'bar'] %>

<% unless ignore_these_fields.include?('abc') %>
  <input type="text" name="abc" value="<%= @vals['abc'] %>" />
<% else %>
  <input type="hidden" name="abc" value="<%= @vals['abc'] %>" />
<% end %>

<% unless ignore_these_fields.include?('foo') %>
  <input type="radio" name="foo" value="<%= @vals['foo'] %>" /> One
  <input type="radio" name="foo" value="<%= @vals['foo'] %>" /> Two
<% else %>
  <input type="hidden" name="foo" value="<%= @vals['foo'] %>" />
<% end %>

<% unless ignore_these_fields.include?('bar') %>
  <select name="bar">
    <option <% 'selected' if @vals['bar']=='a'%>>blah1</option>
    <option <% 'selected' if @vals['bar']=='b'%>>blah2</option>
    <option <% 'selected' if @vals['bar']=='c'%>>blah3</option>
  </select>
<% else %>
  <input type="hidden" name="foo" value="<%= @vals['bar'] %>" />
<% end %>

Here, fairly different HTML form fields get rendered for each type of fields, and in some cases we do not want to show certain fields. So I wanted to do this instead: write a helper that would take a block and render its contents verbatim, otherwise create a hidden field.

<% ignore_these_fields = ['foo', 'bar'] %>

<% render_unless_ignored(ignore_these_fields, 'abc') do %>
  <input type="text" name="abc" value="<%= @vals['abc'] %>" />
<% end %>

<% render_unless_ignored(ignore_these_fields, 'foo') do %>
  <input type="radio" name="foo" value="<%= @vals['foo'] %>" /> One
  <input type="radio" name="foo" value="<%= @vals['foo'] %>" /> Two
<% end %>

<% render_unless_ignored(ignore_these_fields, 'bar') do %>
  <select name="bar">
    <option <% 'selected' if @vals['bar']=='a'%>>blah1</option>
    <option <% 'selected' if @vals['bar']=='b'%>>blah2</option>
    <option <% 'selected' if @vals['bar']=='c'%>>blah3</option>
  </select>
<% end %>

That’s a bit DRYer. But here came the tricky part: the helper. I had done what I thought was right:

def render_unless_ignored (ignoring_array, key)
  unless ignoring_array.include?(key)
    yield
  else
    %Q{<input type="hidden" name="#{CGI::escapeHTML key}" value="#{CGI::escapeHTML @vals[key]}" />}.html_safe
  end
end

The yielded content was showing up but the string result was not! The ERb template was not outputting it. Then a colleague pointed out that in this case we need to tell the ERb template to render the string with concat():

def render_unless_ignored (ignoring_array, key)
  unless ignoring_array.include?(key)
    yield
  else
    concat %Q{<input type="hidden" name="#{CGI::escapeHTML key}" value="#{CGI::escapeHTML @vals[key]}" />}.html_safe
  end
end

And THAT worked!

Learning CoffeeScript: use fat arrow => to ensure @ is the correct “this”

A project I’ve been working on has called for CoffeeScript so I’ve been diving into it. One quirk that happens with JavaScript is the scope of variables bound to the function() enclosing them. So what’s wrong with this?

class FooFoo
  constructor: ->
    @foo = 1
    @some_fn()
  some_fn: ->
    $('#some-button').click (ev) ->
      @foo += 1

That interior @foo inside some_fn() is going to have the wrong this when it compiles out:

var FooFoo;
FooFoo = (function() {
  FooFoo.name = 'FooFoo';

  function FooFoo() {
    this.foo = 1;
    this.some_fn();
  }

  FooFoo.prototype.some_fn = function() {
    return $('#some-button').click(function(ev) {
      return this.foo += 1;
    });
  };

  return FooFoo;
})();

So it’s the => fat arrow (hashrocket in Ruby terms) to the rescue. It creates a function-scoped _this and does the right thing inside now:

var FooFoo;
FooFoo = (function() {
  FooFoo.name = 'FooFoo';

  function FooFoo() {
    this.foo = 1;
    this.some_fn();
  }

  FooFoo.prototype.some_fn = function() {
    var _this = this;
    return $('#some-button').click(function(ev) {
      return _this.foo += 1;
    });
  };

  return FooFoo;
})();

Ah, much better.

Gist: Comparing Sass (SCSS) vs LESS

From 2011 but probably still pretty valid: https://gist.github.com/674726

Note: I’m using Sass and SCSS interchangeably here. The Gist was comparing SCSS vs. LESS.

Quick summary:

  • Very similar. Both awesome.
  • LESS does variable scoping, Sass doesn’t
  • Sass allows selector inheritance
  • Sass’ arithmetic is more flexible
  • LESS has a kind of namespacing
  • Defining variables:
    • Sass: $name: value;
    • LESS: @name: value;
  • Sass mixins are more explicit than LESS (or LESS’ mixins are more succinct):
    • Sass:
      @mixin foo { … }
      { @include foo; }
    • LESS:
      .some-class { … }
      { .some-class; }