Recent Posts

Great Interfaces: The Scale of the Universe

http://htwins.net/scale2/

I love how much information is communicated in such a simple interface. I also like the fact that data appears when it is needed, but doesn't clutter up the screen when it is not needed.

cucumber says, "no such file to load -- spec/expectations"

Setting up a Rails3 application quickly, I ran in to this error...

no such file to load -- spec/expectations

easy fix... I had gem 'rspec' but needed to add gem 'rspec-rails'

Funniest irrelevant argument ever

From Use Mercurial, you Git!

"If I'd wanted building blocks for rolling my own, I'd have gone to Home Depot and bought a 1 and a 0."

MySQL permissions for a Rails app

Here's how I typically setup my rails environments. NOTE: I don't include stored procedure or view permissions because Rails doesn't ever use those. Wouldn't it be great if Rails used views or stored procedures? Actually, I kinda like it the way it is. Stored Procedures are nice but the tradeoff, IE having business logic in the app and in the database, is a high price to pay. As for views, actually, that might be really nice for some reporting things. Maybe that'll be a new gem... :) but for now, stick with these.

DEVELOPMENT MACHINE

I create a dev user and a test machine. For each app, I create app_dev and app_test.

1
2
3
4
5
CREATE USER test IDENTIFIED BY 'somepass'
CREATE USER test IDENTIFIED BY 'somepass'

GRANT ALL ON app_dev.* to dev;
GRANT ALL ON app_test.* to test;

In production I typically have three environments: edge, staging, production. Each has its own database and user.

1
2
3
4
5
6
7
8
9
10
 CREATE USER 'edge'@'localhost' IDENTIFIED BY 'somepass'
 CREATE USER 'staging'@'localhost' IDENTIFIED BY 'somepass'
 CREATE USER 'production'@'localhost' IDENTIFIED BY 'somepass'

 /* note that, counterintuitively,  you do NOT have to */
 /* create these databases first. You can let */
 /* the Rails app do that with rake db:create or whatever. */
 GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX ON app_edge.*
 GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX ON app_staging.*
 GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX ON app_production.*

Capistrano says, "sh: bundle: not found"

Typically, you define your path in /etc/environment. Here's a simple example:

1
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/ruby/bin"

That last bit tells the system where Ruby lives. If Ruby isn't in the path, you won't be able to run it or any gem scripts, like bundle.

Unfortunately, neither /etc/environment nor /etc/profile is respected under certain situations, like the way Capistrano works by default.

The solution for me was to edit /etc/bash.bashrc, adding this as the first line:

1
  source /etc/environment

Note: Adding it as the first line allows / encourages it to be overwritten as needed. If you're still having problems, here's one way to get started with troubleshooting:

edit /etc/bash.bashrc to include this
1
  export USES_BASHRC='bashrc'

edit /etc/profile to include this line:
1
   export USES_PROFILE = 'profile'

then see whether either of those environmental variables is around when capistrano connects. From your dev machine, run "cap shell" and you will end up with a "cap>" prompt. type "echo $USES_BASHRC && echo $USES_PROFILE. Here's what I got:

1
2
3
4
5
   cap> echo $USES_BASHRC && echo $USES_PROFILE
   [establishing connection(s) to www.verdacom.com] 
   Password:
    ** [out :: www.verdacom.com] bashrc
    ** [out :: www.verdacom.com]

Thanks to the SliceHost support team for pointing me in the right direction on this one.

REFERENCES
============
http://stefaanlippens.net/bashrc_and_others

[FIX] With Rails 2.3.x, undefined local variable or method `dep' for Gem:Module

I received this message when I ran cucumber tests but not when I used script/console. Kinda strange. Perhaps this is because I didn't configure cucumber for my dev environment?? Anyway, the fix:

1
2
gem uninstall rubygems-update
gem update --system 1.4.3

In the words of Yoda, "Unfortunate this is, and unexpected."

References
=======
Can not install redmine
Gist -- Undefined local variable dep
RubyGems Developers Mailing List
StackOverflow -- How do you downgrade RubyGems

get Ruby 1.9 Date.parse to assume American date format

Ruby 1.9 assumes that everyone has been broken of the bad habit of illogical date formats.

in the console:

1
2
3
4
5
6
7
8
>> Date.parse('2/15/2011')
ArgumentError: invalid date

>> Date.parse('2/15/11')
ArgumentError: invalid date

>> '2/15/2011'.to_date
ArgumentError: invalid date

While I'm driving everyone crazy by writing the date as YYYY-MM-DD, my clients aren't as OCD. They insist on using the American date format mm/dd/yyyy and it's lazy alternate, mm/dd/yy. Here's the code I wrote to help them with their bad habits.

For my rails apps, in config/initializers/american_date_format.rb:

1
2
3
4
5
6
7
8
9
  def Date.parse(value = nil)
    if value =~ /^(\d{1,2})\/(\d{1,2})\/(\d{2})$/
      ::Date.civil($3.to_i + 2000, $1.to_i, $2.to_i)
    elsif value =~ /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/
      ::Date.civil($3.to_i, $1.to_i, $2.to_i)
    else
      ::Date.new(*::Date._parse(value, false).values_at(:year, :mon, :mday))
    end
  end

Now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>> Date.parse('2/15/11')
=> Tue, 15 Feb 2011

>> Date.parse('2/15/2011')
=> Tue, 15 Feb 2011

>> Date.parse('2011-02-15')
=> Tue, 15 Feb 2011

>> '2011-02-15'.to_date
=> Tue, 15 Feb 2011

>> '2/4/11'.to_date
=> Fri, 04 Feb 2011

My Rails App Just Answered the Phone?

Twilio apparently offers a telephone api and also an SMS API. I get how you could easily set up an SMS API. Pretty cool stuff. But what amazed me what the idea that someone could call a telephone number, which would result in a post to my website... and I would respond with instructions?!?!!

Ladies and gentlemen, the future is now. My rails app just answered the phone.

Cucumber via Envjs says "a.ownerDocument is null"

I recently received the following errors when running capybara with envjs. Strangely, there was a kind of double stack trace. Here are the exeptions:

===
WARNIING: [Thu Mar 10 2011 09:54:41 GMT-0600 (CST)] {ENVJS} Exception while dispatching events: a.ownerDocument is null
a.ownerDocument is null (Johnson::Error)
===

===
WARNIING: [Thu Mar 10 2011 09:54:41 GMT-0600 (CST)] {ENVJS} Exception while dispatching events: a.ownerDocument is null
oopse a.ownerDocument is null
undefined
inline:129 [JavaScript]
===

===diff

--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -1,4 +1,4 @@
-ENV["RAILS_ENV"] ||= "cucumber"
+ENV["RAILS_ENV"] ||= "test"

require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')

@@ -20,7 +20,6 @@ require 'capybara/session'
Capybara.default_selector = :css

require 'capybara/envjs'
-Capybara.javascript_driver = :envjs

Before do
User.test = Factory.create(:user)
===

and for reference:

===
diff config/environments/test.rb config/environments/cucumber.rb

< config.gem 'factory_girl'
< config.gem 'rspec', :lib => false
< config.gem 'rspec-rails', :lib => false
< config.gem 'capybara-envjs', :lib => 'capybara/envjs'
---
> config.gem 'capybara-envjs', :lib => 'capybara/envjs'
> config.gem 'factory_girl'
> config.gem 'cucumber', :lib => false
> config.gem 'cucumber-rails', :lib => false, :version => '>=0.3.2' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber-rails'))
> config.gem 'database_cleaner', :lib => false, :version => '>=0.5.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/database_cleaner'))
===

my complete features/support/env.rb file:
===
ENV["RAILS_ENV"] ||= "test"

require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')

puts "========================================"
puts "RAILS_ENV is #{RAILS_ENV} "
puts "========================================"

require File.expand_path(File.dirname(__FILE__) + '/../../test/helpers/user.rb')

require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
require 'cucumber/rails/world'
require 'cucumber/rails/active_record'
require 'cucumber/web/tableish'

require 'capybara/rails'
require 'capybara/cucumber'
require 'capybara/session'

Capybara.default_selector = :css

require 'capybara/envjs'

Before do
User.test = Factory.create(:user)
Given 'I am logged in'

System.destroy_all
System.load
end

ActionController::Base.allow_rescue = false
Cucumber::Rails::World.use_transactional_fixtures = true

if defined?(ActiveRecord::Base)
begin
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
rescue LoadError => ignore_if_database_cleaner_not_present
end
end
===

Ask Cucumber with Capybara for inline HTML... now with CSS Selectors!

Two very useful cucumber steps:

1
2
3
4
5
6
7
Then 'display the page' do
  puts "\n\n\n#{page.body.to_s}\n\n\n"
end

Then /^display "([^"]*)"$/ do |selector|
  puts "\n\n\n#{find(selector).native.to_html}\n\n\n"
end

When you're remoting in to your dev machine, you can't use "Then show me the page" because there is no desktop in which to open the browser... so I created "Then display the page". It outputs the HTML to the screen for your examination. This becomes very tedious when pages get long... after some help on the capybara mailing list, I created the second entry, which accepts a CSS selector.

Bundler: NOT WORTH THE EFFORT

I've been exposed to bundler on a couple of projects recently.

My impression is that it does a poor job of solving a rare problem, while making common tasks more difficult.

HTML5 canvas notes

Spinner (in german... Chrome translates)
post
example

"Ajaxian: Canvas Loader":http://ajaxian.com/archives/canvas-loading-indicator-for-the-iphone-and-beyond

Apple's Tutorial

[fix for] interpolation syntax in I18n messages is deprecated

Somehow, Rails3 was installed in my 1.8 rvm gemset. rails3 depends on i18n v >= 0.4. Uninstalling i18n (and rails3, since it doesn't run in 1.8 anyway) corrected this issue.

Rails says, "Missing pdf-writer" when pdf-writer is unpacked in vendor/gems

Issue:
*"Missing these required gems: pdf-writer = 1.1.8"*

config/environment.rb:
Issue:
*"Missing these required gems: pdf-writer = 1.1.8"*

config/environment.rb:
1
  config.gem "pdf-writer", :lib => "pdf/writer", :version => '1.1.8'

That looks write... what's the issue? Turns out my new server didn't have the required dependencies.

I added this above the config/gem line:

1
  require "#{RAILS_ROOT}/vendor/gems/pdf-writer-1.1.8/lib/pdf/writer.rb"

and saw:

1
2
  no such file to load -- color
  no such file to load -- transaction-simple      # after fixing color

the fixes:
1
2
  gem install color
  gem install transaction-simple

remove the require line, and voila!

Anthenticating against PayFlowPro for Rails with ActiveMerchant

Rails is fortunate to have ActiveMerchant, a gem that provides a standard interface for billing. Unfortunately, there are a wide variety of gateways out there and each has their own "uniqueness." I experienced PayFlowPro's "uniqueness" today and thought I would share my now-working spike code.

THE PARTNER FIELD

The partner field below is optional. If you leave it blank, the default will be PayPal. The other option, apparently, is VeriSign. I have included it here because magical, undocumented parameters confuse people.

MERCHANT LOGIN

in my case, this was the company name without any spaces. It's the same as the merchant login required to log in to the PayflowPro website.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

  gateway = ActiveMerchant::Billing::PayflowGateway.new(
    :login             => 'my_company_name',    # 'Merchant Login from the login page
    :user              => 'my_username',
    :password          => 'ComPliCatedP4sSw0rd',
    :partner           => 'PayPal'
  )

credit_card = ActiveMerchant::Billing::CreditCard.new(
                      :number => '5105105105105100',
                      :month => '9',
                      :year => '2011',
                      :first_name => 'Longbob',
                      :last_name => 'Longsen',
                      :verification_value => '123',
                      :type => 'master'
                    )

# Make a $1 purchase (100 cents)
response = gateway.purchase(100, credit_card)
puts response.success?
puts response.message

MOVING FROM A SPIKE TO REAL CODE

Copy the above code, replace your company name, and get that to say "Accepted"... once that's done, check back for my blog entry on the easiest way to set up ActiveMerchant in a Rails app.

ISSUES I EXPERIENCED

PayFlowPro response 26 - Invalid Vendor Account

I was using my username where my merchant login should have been.

PayflowPro response 1 - User authentication failed

Here I was submitting the company name as my :login but was not including my username under :user



REFERENCES

com.googlegroups.activemerchant - Payflow Pro Integration

Payflow Gateway - User authentication failed