noizZze

NR Time for Mac OS X

Free notepad for your tasks with time tracking.

Learn More

RSpec and ActionController::Metal

If you like me tried to merry the two, you probably noticed they didn’t like each other. Here’s a small hack to let you test your Metal controllers. For RSpec to work with such controller, we need the following modules:

1
2
3
4
5
include ActionController::UrlFor
include ActionController::Rendering
include ActionController::Testing
include Rails.application.routes.url_helpers
include ActionController::Compatibility

Let’s assume that you have an ApiController that renders some stuff (so it already uses Rendering module). Here’s the sample api_controller.rb code:

1
2
3
4
5
6
7
class ApiController < ActionController::Metal
  include ActionController::Rendering

  def work
    render :text => { :data => 1 }.to_json
  end
end

Now, to test it you need to include all other important modules before the tests, like this (I put it inside the spec file). Here’s my sample api_controller_spec.rb file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require 'spec_helper'

class ApiController
  include ActionController::UrlFor
  include ActionController::Testing
  include Rails.application.routes.url_helpers
  include ActionController::Compatibility
end

describe ApiController do
  it "should return content from 'work'" do
    get :work
    response.body.should == { :data => 1 }.to_json
  end
end

Hope it helps!

Bundler: Quicker Deployments With Shared Bundle

Often when you deploy your app, there are gems that need some native code or gems that need root permissions to be installed into default locations. In most cases you don’t have them or don’t want to use them to be sure the deployment is perfectly “sandboxed”.

Bundler 1.0 solves this problem by introducing the “–deployment” key. When specified during the bundle installation, Bundler creates a “vendor/bundle” directory and places all your gems in it effectively isolating them from the outside environment. Since you own the app directory, there’s no issue with permissions. The downside of the approach is that every time you deploy the application the directory either doesn’t exist or empty and you have to install the same gems over and over. Takes time and space.

Fortunately, that’s easy to fix by linking “vendor/bundle” to a shared location right before running “bundle install –deployment”. Here’s how I do it in my Capistrano deployment script:

1
2
3
4
task :bundle_gems, :roles => :app do
  run "mkdir -p #{shared_path}/bundle && ln -s #{shared_path}/bundle #{release_path}/vendor/bundle"
  run "cd #{latest_release}; bundle install --deployment --without development test"
end

MySQL Gem and “Uninitialized Constant MysqlCompat::MysqlRes”

If you, like me, have upgraded to Snow Leopard and seeing the following error when trying to run your Rails app:

1
uninitialized constant MysqlCompat::MysqlRes

… here’s the quick recipe that can help:

1
2
3
$ sudo gem uninstall mysql
$ sudo -s
# export ARCHFLAGS="-arch i386 -arch x86_64" ; gem install --no-rdoc --no-ri mysql -- --with-mysql-dir=/usr/local --with-mysql-config=/usr/local/mysql/bin/mysql_config

What it does is setting the correct architecture flags along with the proper paths necessary to build native code.

Gem Is in the List but Doesn’t Load

Here’s another quick tip. If you can see a gem in the list of your installed gems

1
2
3
4
5
→ gem list mysql

*** LOCAL GEMS ***

mysql (2.8.1)

… but when you try loading it, it doesn’t work

1
2
3
4
5
6
→ irb
>> require 'mysql'
LoadError: no such file to load -- mysql
  from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
  from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
  from (irb):1

… make sure that you don’t have stale Gem specifications hanging around in the Gem paths. Sometimes you have a Gem installed in the system folder (/Library/Ruby/Gems/1.8), but a stale Gem specification (for example, mysql-2.8.1.gemspec) sitting in your local user Gem folder (~/.gem/ruby/1.8). Remove the stale spec and you are golden.

PGP for Mortal Developers

Why do I need it?

PGP has two main purposes – signing and encryption. When you sign a document (letter or file), you let the recipient know who is the origin and be sure the document wasn’t altered on its way.

Encryption doesn’t let anyone except the recipient to see the contents of the document.

We, programmers, can use this feature in many practical cases. Here is just a couple of them:

  • Store a secret file with passwords and configuration details that’s intended for your development team only in the open (version control repository)
  • Exchange sensitive messages with clients (invoices, server account passwords, confidential information)

How does it work?

Everyone has two keys – public and secret. Public keys you give away to people you want to be able to send you encrypted documents. In return, if they want you to send them encrypted documents, they give their public keys to you. This is important concept to understand – you can encrypt documents with public keys of recipients. In other words, you can send documents only to the people in your “PGP address book”.

Secret keys are kept in secret (read-only media stashed somewhere secretly comes to mind). You use them to open encrypted documents that are addressed to you by others. Under no condition do you hand it over to anyone.

Usually, to share public keys, (a) you send them directly via e-mail, (b) publish on your web site, or (c) publish them on key servers (for example, pgp.mit.edu). Think of the key server as a directory of keys. You can find people you know there if they use PGP. Some well-known key servers synchronize their records, some not.

Once you have your own key, you may want to start exchanging it for keys of the members of your team, family, friends and clients. When you get a key from the person you trust, you can sign it thus building the trusted web of keys. It starts to really work when some friend of a friend sends you his key, and you see that Gus trusts him while you trust Gus, so that’s probably OK to trust and sign. Note, that it’s not about the trust between people, as you might think, it’s the trust in that the key you’ve been given does really belong to that person (not forged).

When you have a directory of keys, you can now start signing documents (again, letters, files) and sending them over to your contacts. They will be able to open them.

How to configure?

First, you need a key if you don’t have one:

$ gpg --gen-key

… is what you do. Answer the questions and wait while the key-pair is generated. The common choice is 1024-bit “DSA and ElGamal”, but you may choose more bits. The encryption will be slower, but you won’t notice it on modern hardware unless you are encrypting wikipedia. DSA lets you sign your documents, and ElGammal give the encryption. Usually people don’t use expiration at all if it’s not a mission critical temporary key. Don’t forget the passphrase. It’s important to protect your keys.

Manuals recommend creating a revocation key to be able to revoke your keys in case of theft or bad pass phrase memory:

$ gpg -o revoke.asc --gen-revoke my_key_id

Now you can see your key in the list:

$ gpg -k

To export the key in binary form and give it to someone use:

$ gpg -o john.gpg --export my_key_id

To get the same key in plain text, add the ‘–armor’ key:

$ gpg -o john.gpg --armor --export my_key_id

(you can omit ‘-o …’ to get it all in stdout)

When someone sends you a key, you can import it with:

$ gpg --import mark.gpg
$ gpg -k

If you trust the key, sign it:

$ gpg --sign-key key_id

When you are ready to send your key, find the server (i.e. pgp.mit.edu) and submit your key either through the web interface or using the gpg command again:

$ gpg --keyserver pgp.mit.edu --send-key my_key_id

How to sign?

Now that you have your key, keys of your recipients and documents to protect, here’s what you do.

To sign a document there are two ways – clear text and binary with optional compression.

When you have a plain text document that you want to sign leaving it legible, you choose clear text signing. It will add the plain text block with your signature to the bottom of your document. If anyone touches the document, the signature won’t match the content and it won’t be your authentic copy any more.

$ gpg --clearsign document.txt

When you have a binary document or want to compress along with signing and additionally protect from change:

$ gpg -o doc.txt.sig --sign doc.txt

To verify the signature of the document that’s sent to you:

$ gpg --verify doc.txt.sig

To get the original (doc.txt):

$ gpg doc.txt.sig

How to encrypt and decrypt?

When you need to encrypt a document, you choose the recipients first and then use their public keys from your “keychain” (gpg -k) to create the encrypted version.

$ gpg -o doc.txt.gpg -e -r mike -r robert doc.txt

NOTE: You won’t be able to open the file if you don’t include yourself into the recipients list.

To decrypt the file:

$ gpg doc.txt.gpg

What else?

Once you are familiar with these simple tools, you may want to start exchanging protected e-mails with your co-workers, clients and friends. Many e-mail client support PGP these days.

Today, as we store our mail on the servers of giant Internet companies, it’s a norm to feel uncomfortable knowing that anyone can read your correspondence. Let’s make it a little bit harder.

That’s all folks. If you notice any inaccuracies, or have any suggestions, please let me know. I’m not an expert in this area at any stretch of imagination. This is just a quick summary for those who want to start quickly. You can find more info on official web site: http://www.gnupg.org.

PayPal Scam

As you know, we are heading back home from Australia soon and selling our stuff. We advertise it in multiple places, but mainly on Gumtree. It’s been mainly pleasant experience so far, and I’ve got a couple of good leads from this site.

What I would like to share with you is one PayPal scam that we almost fell victims of today. It all started in the morning when I got this mail from someone who supposedly wanted to buy our bedroom set. He asked for the lowest possible price and then came back with an interesting message where offered slightly more than I asked and told that he just moved to UK. He wanted to pay immediately and instruct his shipping agent to pick up the furniture. He offered to pay full price via PayPal and (politely) asked if I had more pictures since he’s unable to inspect the stuff himself.

That alone was suspicious enough, but at that moment we didn’t see how was it possible to scam us. I expressed how surprised I am to hear that he ships this furniture overseas, but told him my PayPal email address to transfer the payment to as agreed.

After this I get an email with the request to remove the ad and to provide my home address for pick up. At this point I started to feel something isn’t right…

I do a quick search and find that most online auctions and ad sites warn you about this scenario – someone offers you a great deal (that’s why they pay you more than you ask), they pay you straight away to your PayPal account, then you ship your stuff to an unverified location (or better yet, they pick it up locally and drive away in an unknown direction).

Now the fun part comes when PayPal figures that either the credit card was stollen, or they used the cheque that can’t be debited to your account and you lose your money. If you were lucky enough and withdrawn the cash from your PayPal account disconnecting your real account and CC from it, the worst that happens is that your PayPal balance goes negative and you are unable to use PayPal until you repay.

In my case, since I already sent them my PayPal email, I had to quickly disconnect it from my account. It would have been extremely unpleasant to find them sending me the payment. So I made everything possible not to receive it in the first place.

So how did I know it was the scam. I didn’t. At least not for sure, but there are some signs that made me suspicious:

1. They offered more than I asked. Looks like a lure. Have you ever seen anyone offering you more than you ask? I mean, Ever?

2. They agreed to any my conditions without any discussions. I wanted to keep furniture until the very date of departure. However…

3. They wanted to pay fast and take the ad off the site. In fact, they wanted to pay me NOW. In every letter I could see at least a couple “immediately”.

4. Is there any furniture in UK? What’s the point in purchasing it here and spend $2k on shipment? That’s stupid if nothing else. I’m not selling rarities after all.

My final response was the polite decline of the deal on the grounds that PayPal payments don’t look secure in this context and that I was advised not to accept them. Never heard from them before.

I hope this helps someone and saves from a lot of trouble. Trade safely!

Rails: Creating Associated Objects in AR

Assuming that you have an object Account like below

1
2
3
class Account < ActiveRecord::Base
  has_one :office
end

and you want to create an Office record when you create an account, you could do it in the after_create filter and it would be my way of doing that also. But the funny thing is that if you name the filter create_office, you don’t need to define the method itself. It will create the Office and link it to your Account model automagically. So here’s how the final class definition looks like:

1
2
3
4
class Account < ActiveRecord::Base
  has_one :office
  after_create :create_office
end

Amazing!

Going Home

We decided to head back home next month. Yeah, just like that.

It was a life-changing journey to Australia that we enjoyed greatly and that gave us so many insights and new angles that we couldn’t possibly have otherwise. Our decision is based on that living here doesn’t align with our personal plans very well. We figured that more than everything we love our families and immensely value their support network.

The other reason is that even though the life is more structured here, the financial well-being is way harder to achieve. Technically speaking, we had a serious downgrade on multiple fronts, and figured all the trouble of settling in a new world is not worth it. Don’t take me wrong, Australia is amazing. It’s that in our particular case we have some better options.

We have our tickets and depart on June 24. Now comes the time of selling our newly purchased stuff – furniture, kitchen and laundry equipment, the car. I will be posting listings shortly. Drop me a line if you are interested in seeing what’s on offer.

Wish us luck!

Design Thoughts: Blank Slates

Here’s an interesting article by 37Signals on blank slates. For those, who doesn’t know, blank slates are the pages you see in web applications when there’s nothing to display yet – no blog posts or projects or anything else to list on the page. This is an important concept as you don’t want the user to stare at the empty screen. These pages are used to provide guidance and give advice on how to proceed.

It was a great reminder to me, as a web developer. Moreover the speculations behind all this were also very insightful; especially the part when you have to give an impression that it’s all very simple. One thing I didn’t like about the final design though, is the unfinished look of the page – a gray background with some text, an icon and a button. I understand that simplicity is a key, but in this case it looks over-simplistic to the point when it verges on ugliness unprettiness.

In any case, it’s a very good read and highly recommended. Enjoy!

Financial Model Training

Logo

Jason Kotchoff, one of the guys I’ve been working with since my arrival in Australia, has just started a new venture – Financial Model Training. I’m not into investment banking and corporate finance myself, but you may want to have a look if it’s what you do or want to be doing in the future. Good stuff!