Available for hire
Mark Gandolfo

Here are some thoughts of mine.

Curl From Within Text Mate

I have created a small command for textmate that lets you curl a file from within textmate. The source is on github Installation

git clone git://github.com/markgandolfo/tmbundle.curl.git

Navigate to the download directory and double click on the curl.tmbundle file

How to use

^ ⌥ ⌘W will pop a dialog box up, place the url in text field and press enter. The file will download and your project drawer (or project+ drawer) will refresh! Possible Todo

  • Add progress bar for larger files
  • Possibly download to the current open file path (maybe add a checkbox or something)
  • Maybe add some sort of output if the url can’t download for some reason (404, 500, etc.)

How To Alias A Class Method In Ruby

To alias a class method, you can’t just use the alias/alias_method methods. Lets say we have a simple System Event class that has a log() method.

class SystemEvent
  def self.log
    // Do things in here (maybe database / file log depending on log levels)
  end
end

If for some reason we would want to alias log to be log_me, Then I would have to lay out my class as follows

class SystemEvent
  def self.log
    // Do things in here (maybe database / file log depending on log levels)
  end

  class << self 
    alias :log_me :log
  end
end

Changing The Cookie Domain Path In Rails

In rails 2.3.4+ if you want to modify your cooking information set by your system, in any of your environment files you can simple overwrite them as follows.

config.action_controller.session = {
:session_key => '_my_session_id',
:secret => '..your_secret_code_here..',
:domain => ".domain.com"
}

Obviously if you only want to change your domain for instance you can simple do

config.action_controller.session[:domain] = ".domain.com"

Git Tips

I’ll just post a few quick little command line git commands. Basic Commands Sync the meta data (e.g. branch names, tag names, etc) with remote.. This will not update the branches, just the names, etc.

git fetch

To see a list of remote branches

git branch -r

To see a list of local branches

git branch

or

git branch -l

To see both local and remote

git branch -a

Branching To create a new branch from the branch you are currently on.

git checkout -b new_branch

To delete a branch

git branch -d new_branch

To delete a remote branch

git push origin :new_branch

To checkout into a new branch, and merge uncommitted changes

git checkout -mb new_branch

To checkout into an existing branch, merging uncommitted changes

git checkout -m existing_branch

Checkout a remote branch (one that you haven’t checked out before)

git checkout --track -b branch_name origin/branch_name

Tags To tag at the current point in time on the current branch

git tag new_tag

To push tag to a remote

git push --tags

To delete a tag (locally)

git tag -d new_tag

To delete a tag from a remote

git push origin :tags/new_tag

Rails Plugin: Associated With?

Associated With is a simple ruby on rails plugin that will check if an object is associated with another object. has_one and belongs_to

class Computer < ActiveRecord::Base
  belongs_to :programmer
end

class Programmer < ActiveRecord::Base
  has_one :computer
end

So if, Programmer with id 1, is associated with Computer 1, but not Computer 2 using associated_with? we will return

programmer = Programmer.find(1)
computer = Computer.find(1)
computer2 = Computer.find(2)

programmer.associated_with?(computer)
# => true

programmer.associated_with?(computer2)
# => false

We can even do it the other way around

computer.associated_with?(programmer)
# => true

This will work with all associations with ActiveRecord, for example, a has_many :through

class Analyst < ActiveRecord::Base
  has_many :document_stores
  has_many :documents, :through => :document_stores
end

class Document < ActiveRecord::Base
  has_many :document_stores
  has_many :analysts, :through => :document_stores
end

class DocumentStore < ActiveRecord::Base
  belongs_to :document
  belongs_to :analyst
end

so if document 1 is associated to analyst 1 & 2, but not 3. then

Analyst.find(1).associated_with(Document.find(1))
# => true

Analyst.find(3).associated_with(Document.find(1))
# => false

Check out the tests for more information.


How To Integrate Delayed Job Into Your App

So a quick how to integrate delayed job into your app, since i’ve found a lot of the tutorials out there leave out some crucial information. Firstly, I used Tobi’s delayed_job since it comes with a few extra bits a pieces, like generators and the like. Install the plugin You can either install it using the rails command, or use git submodules (which i won’t cover here)

script/plugin install git://github.com/tobi/delayed_job.git

Generate and run the migration We’ll run the generator script to generate our migration and then migrate the database up

script/generate delayed_job_migration

Which will generate a migration that looks like this. Have a read through the file. You’re probably asking yourself where the object to be run is stored. Its actually stored in the “handler” field as a sexy yaml field.

  create_table :delayed_jobs, :force => true do |table|
    table.integer  :priority, :default => 0      # Allows some jobs to jump to the front of the queue
    table.integer  :attempts, :default => 0      # Provides for retries, but still fail eventually.
    table.text     :handler                      # YAML-encoded string of the object that will do work
    table.string   :last_error                   # reason for last failure (See Note below)
    table.datetime :run_at                       # When to run. Could be Time.now for immediately, or sometime in the future.
    table.datetime :locked_at                    # Set when a client is working on this object
    table.datetime :failed_at                    # Set when all retries have failed (actually, by default, the record is deleted instead)
    table.string   :locked_by                    # Who is working on this object (if locked)
    table.timestamps
  end

How to queue mail in your app Lets say for example we have a AccountsMailer

class AccountMailer < ActionMailer::Base  
  def confirm(user)
    subject       'Your account has been created'
    recipients    user.email
    from          'you@email.com'
    sent_on       Time.zone.now
    content_type  'text/html'
    body "Welcome Aboard"
  end
end

We would normally send an email by doing something like this in our controllers

AccountMailer.deliver_confirm(@user)

With delayed job, we can simply do a

AccountMailer.send_later(:deliver_confirm,@user)

So delayed job adds a send_later class method, which takes an AccountMailer class method as its first param, and then the methods params as the next. How to send the mail Setting up actionmailer is outside of the scope of this post. So i’m assuming you have it set up already. The jobs at this stage are being queued in your database, but we haven’t started any sort of job to process the queue. To start the queue simple run

rake jobs:work

You should see the queue starting to process, or at idle if its empty. This is great, but what happens if the rake task dies for some reason???? Daemons to rescue!!! Daemonising delayed job queue processor First install the daemons gem

sudo gem install daemons

Next create a script in your script/ directory.. I called mine delayed_job

#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))

daemon_options = {
  :multiple   => false,
  :dir_mode   => :normal,
  :dir        => File.join(dir, 'tmp', 'pids'),
  :backtrace  => true
}

Daemons.run_proc('job_runner', daemon_options) do
  if ARGV.include?('--')
    ARGV.slice! 0..ARGV.index('--')
  else
    ARGV.clear
  end

  Dir.chdir dir
  RAILS_ENV = ARGV.first || ENV['RAILS_ENV'] || 'development'
  require File.join('config', 'environment')

  Delayed::Worker.new.start
end

Save that, and you can now simple do the below to start the queue.

script/delayed_job start

I would recommend reading up on the delayed_job and daemons extensions to understand the inner workings, but at least this is enough to get you up and running! notes You can also clear the queue by running

rake jobs:clear

Paypal Sandbox: How To Verify A Bank Account And Get The Api

After about 6 hours today of pulling my hair out and trying to verify my bank account on my sandbox, I finally stumbled across a post that helped me do this For everyone else that is having a hard time getting the bank account to be verified, the secret is the BSB number. Do they tell you this anywhere? Well maybe, but do we look, hell no! Here are some step by step instructions on getting it working! Prerequisites:

  • Create a user account to access the Developer Central Sandbox.
  • Log in to the Sandbox account
  • Create a Test Account of type ‘seller’.
  • This will throw an error message on saving, but it will still create the account.
  • Click the Test Accounts tab to see the account it created. Create Confirm the email address:

  • Create business test account (done in prerequisite above)

  • Log into PayPal Sandbox with test business account details created earlier.
  • Go to Profile Tab
  • Go to Email
  • Choose the email address and click ‘Confirm’
  • Go back to the Sandbox Test Environment and click the Test Email tab
  • Open the email with subject line ‘Activate Your PayPal Account’
  • From the email body, select the confirmation URL and paste into new browser window – it will load the PayPal site (in sandbox mode).
  • Log in with business account.
  • . From the landing page, click the ‘confirm email’ link in the ‘To Do List’ box.
  • . Click the ‘click here if a link doesn’t appear in the email’ link.
  • . Paste in the confirmation number from the email in step 8, and click confirm. A confirmation of success should be displayed.
  • . Click Continue. Create Bank Accounts For Test Business Account:

  • Click the Profile tab

  • Click Bank Accounts link
  • Create a fake bank account. Test Bank. Use BSB 242-200 for Australia. Any random integer for account number, so long as it’s not already being used by another PayPal account. I ended up having to mash the keypad until I found an unused number.
  • Confirm the bank account by clicking the ‘confirm’ link after the step above.
  • Step 17 loads another page where you need to click ‘Submit’.
  • Step 18 loads another page where you need to click ‘I Agree’.
  • The account should now be verified.
  • Click the Profile Tab again.
  • Click API Setup
  • . Click Request API Credentials
  • . Select API Signature
  • . Click I Agree, Click Submit.
  • . Copy the details to a safe place for later reference. Developer Central Sandbox

  • Go back to the Developer central sandbox and login with your account details created in the prerequisite section of this document (i.e., not your test business account, but your actual Developer Central Sandbox account).

  • The Test business account should now be verfied.
  • Click API Credentials tab.
  • The API credentials obtained in step 26 should appear.

Comments

Liam: Thanks for the info! After a few hours butting heads with PayPal sandbox I finally have IPN setup thanks to your instructions.


Using To Param Ftw

I have a client who draws comics. He wanted the url to be /comics/12-02-2008 (where 12-02-2008 was the date the comic was published). I tried for a long while, and finally got my routes to do :controller/:action/:published_on instead of the standard :id. I did this only for the comics controller, and all others had :controller/:action/:id. I kicked myself when I found to_param!

class Comic < ActiveRecord::Base
    def to_param
        "#{id}-#{published_on}"
    end 
end

This allows me to convert the :id symbol to :published_on. Much nicer than the old crusty routes!


Active Resource To A PHP App

Lately I’ve been getting into rails, what can I say its a nice clean language. I also run a forum, its a forum written in php. Now I want to build apps for my php (vbulletin) forum, but I didn’t want to do cross site database calls. I wanted my plug ins to be as independent as possible from the main vbulletin app.. In another website I’ve been writing, there are three components that interconnect to each other using activeresource! Since it was so easy to implement I thought I’d give it a go cross programming language! Heres how I did it! First in PHP create your restfull program! I called mine rest.php :) I know very original! Using a sexy XML library I created for php. From this simply class, I can easily create from a select from a database my xml!

fetch_array($result);
        $xml->openTag("user");      

        foreach ($user as $tag => $value) {
            $xml->addfield($tag, $value);
        }
        $xml->closeTag();
    }
    echo $xml->build();
?>

So far so good! So if we go to file.php?user=1 we should get the user with id 1.. You could add all sorts of cool things here. But this is just an example to get you guys going. Now finally ensure you have mod_rewrite working in apache! now if your php file is called rest.php, you’ll need this rewrite rule to make the magic happen. Just add it to a .htaccess file, or in your vhost RewriteRule ^/rest/users/(.*) /rest.php?user=$1 In your rails app, now create a model named User, e.g. models/user.rb, and add

class User < ActiveResource::Base
  self.site = "http://domain.com/rest/"
end

and don’t forget your corresponding controller. This will now fetch all requests from our rest.php file. If you need any help, please drop me a line! Now for our rails app in our model if we have set up

class User < ActiveResource::Base
  self.site = "http://domain.com/rest/"
end

And we can simply do this in our rails app! You’ll see below the find method on the user model, and the resulting url it’ll call.

User.find(:all)      # http://domain.com/rest/users.xml
User.find(1)        # http://domain.com/rest/users/1.xml
User.find(100)    # http://domain.com/rest/users/100.xml

So if your doing an :all, the app will look for model.xml. If your doing any other call, it’ll look for model/?.xml. I hope this helps when building external active resource communicators.


Ruby On Rails In Gedit

There are a few tutorials out there to make gedit act like textmate..I usually use textmate, but there are some occasions where it just isn’t possible, so I go back to gedit while on linux. Heres how to rubify your gedit!

First Install the plugins for gedit

sudo apt-get install gedit-plugins

Next, visit Insane Terminology as he has a good explanation on how to get syntax highlighting working in gedit! I’ll summarize for the impatient. If you have any installed mime packages in Override.xml remove them

rm ~/.local/share/mime/packages/Override.xml

Next we go to where the real mime packages/definitions are stored and download the mime type definitions courtesy Insane Terminology

cd /usr/share/mime/packages
sudo wget http://robzon.kapati.net/rails/rails.xml 
sudo update-mime-database /usr/share/mime

Now to finish it up, we’ll get syntax highlighting corrected for .rhtml (.html.erb) files.

cd /usr/share/gtksourceview-2.0/language-specs/
sudo wget http://robzon.kapati.net/rails/rhtml.lang

Theres a heap of plugins for gedit, search the net for them, they transform gedit from windows notepad to a real ide. One thing I will mention, I have created shortcut on my top panel (taskbar, or whatever you want to call it). I’ve edited the gedit properties (i.e. right click —> properties) and changed

gedit %U

to

gedit %U --new-window

This allows multiple gedit windows