undefined method `relation’ for nil:NilClass on Heroku

I host almost 100% of my open source projects on Heroku, it’s amazing how easy it is to setup and how “out-of-your-way” they are.

Today, while working on one of my open source project I encountered this error:

It was right after I deployed and migrated the database.

After about 5 minutes of head scratching I came across an answer on stackoverflow saying you have to restart your app after a migration for it to pick up on schema changes.

Had a DAH! moment there :-)

10 Things You Didn’t Know Rails Could do

James Eduard Grey published a presentation of a talk he did in RailsConf.

It is pure gold, so many tips and tricks, I promise you, some of these will be new even to the most experienced of Rails developers.

10 Things You Didn’t Know Rails Could do // Speaker Deck.

With GOV.UK, British government redefines the online government platform – O’Reilly Radar

Reading this article made me realize there’s hope in making government sites better.

The state of the government sites in Israel for example is shameful, all written in .Net, no standards and no cross-platform consideration.

It’s a very good read.

Why create an open source stack? “Why not?” asked Bracken. “It’s a government platform, and as such it belongs to us all and we want people to contribute and share in its development.”

via With GOV.UK, British government redefines the online government platform – O’Reilly Radar.

Kill all resque workers with a single command

At Gogobot we are running background processes with Resque.

We are using God to start workers on all servers, both front end and back end (with different queues).

God sometimes has an issue with leaving some stale workers laying around which cache old code, so if you change your code, this is your enemy since you start seeing failed jobs that should not fail what so ever.

Even when you stop the rakes (Workers run by rake) with god, it will still leave those lying around.

In one word, Frustrating…

So, I was IM’ng with Chiu-Ki and we were talking about killing workers, and I was telling here how to kill those.

She told me she has a shell script for it.

There you go…

and if you just want to test before doing some killing, you can run this:

Of course after this GOD will restart the workers with the new code and that’s it, you have fresh workers, with new code, ready to be up and running.

Rails uninitialized constant Resque::Server

One of the most significant changes in my migration of a rails app from Rails 2.3.10 to rails 3.0.9 was the move from delayed_jobs to resque.

Resque is a Queue system that’s based on Redis, which is much faster and reduces the load on your database. Also we were experiencing some nasty deadlocks with delayed jobs that really broke our transactions and our backs.

I installed the gem and installed Redis on my development machine, mounted the Sinatra app on my rails app and navigated to the web view of resque.

Then, I saw this error:

[ruby]
RuntimeError at /resque/overview
ERR unknown command ‘server’
file: client.rb location: call line: 47
[/ruby]

Which looked like that:

After doing some digging into the code (as I always do when I encountered a problem with a gem), I found that the version of the gem (resque) I was using called the “server” method on the redis instance which was not there any more.

Looking at the code for the new gem showed that the app is now using the property “redis_id” which looks like this:

[ruby]</span>
<pre> def redis_id
# support 1.x versions of redis-rb
if redis.respond_to?(:server)
redis.server
elsif redis.respond_to?(:nodes) # distributed
redis.nodes.map { |n| n.id }.join(‘, ‘)
else
redis.client.id
end
end
[/ruby]

Upgrading the gem to the newest version solved my problem and everything got back to normal.
So, if you encounter this issue, just upgrade the resque gem and you are all good.

The gem version I was using was “resque (1.8.2)”, now I am using “resque (1.18.2)”

As always, if this post was helpful, drop me a comment, I would love to hear.

Uninitialized constant Syck::Syck (NameError)

It’s old news for you devoted reader, but as you know I love coding with Ruby on Rails  and that’s what my story for today is all about.
I just spent about an hour scratching my head and throwing my keyboard (don’t tell Jobs) around my home office on this issue.

I am upgrading an existing project (guess which…) from rails2 and ruby1.8.7 to rails3 and ruby 1.9.2.

First thing is of course installing bundler and working with the Gemfile (thank god).

So, when I did “bundle install” it crashed on me with this error message:

[shell]
Fetching source index for http://rubygems.org/
/Users/avitzurel/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/specification.rb:289:in `load’: uninitialized constant Syck::Syck (NameError)
from /Users/avitzurel/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/specification.rb:289:in `_load’
from /Users/avitzurel/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/spec_fetcher.rb:133:in `load’
from /Users/avitzurel/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/spec_fetcher.rb:133:in `fetch_spec’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/remote_specification.rb:47:in `_remote_specification’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/remote_specification.rb:53:in `method_missing’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:101:in `block in __dependencies’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:98:in `each’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:98:in `__dependencies’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:68:in `activate_platform’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:317:in `resolve_requirement’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:287:in `block in resolve’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:286:in `reverse_each’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:286:in `resolve’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:160:in `start’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:128:in `block in resolve’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:127:in `catch’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/resolver.rb:127:in `resolve’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/definition.rb:151:in `resolve’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/definition.rb:90:in `specs’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/definition.rb:85:in `resolve_remotely!’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/installer.rb:43:in `run’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/installer.rb:8:in `install’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/cli.rb:220:in `install’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/vendor/thor/task.rb:22:in `run’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/vendor/thor/invocation.rb:118:in `invoke_task’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/vendor/thor.rb:263:in `dispatch’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/lib/bundler/vendor/thor/base.rb:386:in `start’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/gems/bundler-1.0.17/bin/bundle:13:in `<top (required)>’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/bin/bundle:19:in `load’
from /Users/avitzurel/.rvm/gems/ruby-1.9.2-p290@rails_3_gogobot/bin/bundle:19:in `<main>’
[/shell]

After digging around the web, reading some useless information that it’s relevance to my issue was close to zero, I updated rubygems on my system to the latest version and this solved the problem.

I executed this command:

[shell]
gem update –system
[/shell]

Hope this saves you some time, if it does, drop me a comment let me know.

Thanks!

Foursquare live updates with the Push API using rails

Recently, I have been working extensively with the Foursquare API, also contributing to the open source foursquare2 gem.

While working on these features, I got a sneak peak preview to the new push API through Foursquare. Until I got that, I needed to pull checkins for each user, which was a slow and unefficient process.

Facebook had this feature for a while that for every checkin a user has, the application (he authorized) get a push notification to a callback URL – this is highly effective and more streamlined process.
So, Foursquare added it and like I said, I was happy to get a sneak peak to it.

Since it has no documentation yet, adding it to the application was not as smooth as I am used to, so I thought I would post the code for it on my blog, so you will have it easier then me :-)

Foursquare posts the json for the checkin to your controller with no parameter, so you need to use the post body in order to read it.

Here’s the controller code:

[ruby]
class FsRealtimeController < ApplicationController
protect_from_forgery :except => ‘post’

def post
posted_json = request.body.read

if posted_json.blank?
render :nothing => true
return
end

parsed_json = JSON.parse(posted_json.to_s)

# Do whatever you want with the parsed json

render :nothing => true
end
end
[/ruby]

The typical json will look something like this:

[js]
{
"checkin": {
"createdAt": 1298129668,
"id": "4d5fe304d7206ea8e90aeef1",
"shout": "#4sqhackathon",
"timeZone": "America/New_York",
"type": "checkin",
"venue": {
"categories": [
{
"icon": "http://foursquare.com/img/categories/building/default.png",
"id": "4bf58dd8d48988d125941735",
"name": "Tech Startup",
"parents": [
"Home / Work / Other",
"Corporate / Office"
],
"primary": true
}
],
"contact": {
"twitter": "gnrlassembly"
},
"id": "4c5c076c7735c9b6af0e8b72",
"location": {
"address": "902 Broadway, 4th Floor",
"city": "New York",
"crossStreet": "btw 20th and 21st",
"lat": 40.739197437761383,
"lng": -73.989760279655457,
"postalCode": "10010",
"state": "NY"
},
"name": "General Assembly",
"stats": {
"checkinsCount": 1357,
"usersCount": 557
},
"todos": {
"count": 0
},
"verified": false
}
},
"user": {
"firstName": "Neil",
"gender": "male",
"homeCity": "New York, NY",
"id": "2097",
"lastName": "Sanchala",
"photo": "http://playfoursquare.s3.amazonaws.com/userpix_thumbs/0QYGOJMDGLTJOOQG.jpg",
"relationship": "self"
}
}
[/js]

You can find some more details here (json from the link).

Install Membase 1.6.5.3 on Amazon EC2 and configure it on EBS

As your application grows (like ours did) you will need more space to store your cache.
In our case, we needed to move from memcached to membase and make use of both memory and disk space. The decision was made and we decided to go with a 2 server solution, each server has 16G of memory and 100G of EBS volume attached to it. Also, both will have membase latest stable version installed and perform as a cluster in case one falls or anything happens, a fail safe if you will.

In this post, I will walk you though what was done to perform this and how exactly it was done on the amazon cloud.

First things first, select an AMI from your list and click on “Launch instance”.

Launch an instance from an AMI
Launch an instance from an AMI

You will see a dialog popup where you need to select the instance type.

Select instance type on Amazon
Select instance type on Amazon

I selected the 16G memory server, I launched 2 instances from this type. Like I said before, I wanted those to perform in a cluster so I will have a fail safe option.

Now, you have 2 servers up and running. Because those servers are serving as a membase solution to production servers, I also configured an elastic IP to them.

Now, let’s create our volumes.

Creating EBS volumes and attaching to your instance

Go to the EBS section and click on create volume (top right in this image).

Create an EBS volume
Create an EBS volume

You will see this dialog:

Select the size of your new EBS volume
Select the size of your new EBS volume

Just select how many Gigs you want, availability zone (make sure it’s the same as the server availability zone or you will have performance issues).

Once the EBS volumes (I needed 2) are ready, all you need is to attach those to your servers.

You right click on the volume and select “attach”, you will see very detailed information about what you need to do there (very simple)

OK, so now we have our servers and volumes attached to them (instances don’t “know” the EBS’s yet).

SSH into your instance.

Mounting your EBS volume to the instance

After you ssh into your instance run these commands to have your volume installed on the instance (You can mount in another folder and not the one I selected here).

[shell]
yes | mkfs -t ext3 /dev/sdf
mkdir /mnt/data-store
mount /dev/sdf /mnt/data-store
[/shell]

This will mount the EBS to the /mnt/data-store folder, which we will use in a few minutes to have membase work on this folder and not steal space from the server main disk (which will result in a crash).

Downloading and installing membase on your new instance

First, a cleanup…

I had the instances created from an AMI that already had a previous version of membase (1.6.4) installed on it. So first, you will need to clean those up like so:

[shell]
rpm -e membase-server-
[/shell]

I ran this:

[shell]
rpm -e membase-server-1.6.4
[/shell]

Now, go to membase.com, register for the download and you will be able to download the package you need, you can select from a variety of versions.

Couchbase website, select your download
Couchbase website, select your download

Copy the download link and go back to your server.

Put this in your shell and click ‘Enter’.

[shell]
wget your_download_link
[/shell]

I have a server with RPM but it’s all the same with another package manager.

After you have the file downloaded to the server, run this command:

[shell]
rpm –install your_rpm_file.rpm
[/shell]

Now you have membase installed on the server. Congrats!
All should be running now.

Configuring the membase server after installation

From here, you can read the getting started in the membase wiki, it’s very good from here on:

http://techzone.couchbase.com/wiki/display/membase/Getting+Started

SSL verification issue with the Foursquare2 gem [Solved]

I’ve been implementing a Foursquare API into a website using the foursqaure2 gem.

While working on development, everything went smooth, tests passed and it was really cool to work with. However, once I deployed staging and production I immediately encountered the well known SSL issues.

[shell]
SSLv3 read server certificate B: certificate verify failed
[/shell]

The solution actually wasn’t that trivial, I monkeypatched the gem so you can pass an SSL hash and refer to the ca_file.

This has solved the problem.
Notice the @ssl param, this is the important thing here.

[ruby]
def initialize(options={})
@client_id = options[:client_id]
@client_secret = options[:client_secret]
@oauth_token = options[:oauth_token]
@ssl = options[:ssl].nil? ? Hash.new : options[:ssl]
end

# Sets up the connection to be used for all requests based on options passed during initialization.
def connection
params = {}
params[:client_id] = @client_id if @client_id
params[:client_secret] = @client_secret if @client_secret
params[:oauth_token] = @oauth_token if @oauth_token
@connection ||= Faraday::Connection.new(:url => api_url, :ssl => @ssl, :params => params, :headers => default_headers) do |builder|
builder.adapter Faraday.default_adapter
builder.use Faraday::Response::Mashify
builder.use Faraday::Response::ParseJson
end
end

def ssl
@ssl
end
[/ruby]

This is how you pass the hash

[ruby]
client = Foursquare2::Client.new(:oauth_token => self.fs_oauth_token, :ssl => { :verify => OpenSSL::SSL::VERIFY_PEER, :ca_file => "path_to_your_pem_file" })
[/ruby]

If you are running on Amazon or any other cloud solution and you don’t know where your SSL certification is located, there’s a tip in this post on how you can find it.

Like a good Ruby on rails and open source developer, I issued a pull request to the original gem’s developer and this fix will be in the next version of the gem, you can find it here

If you are having issues with SSL, just pay attention to what version of the gem you are running and make sure you are running a version with this fix.

Solving the SSL issue with the Rapleaf API

While working with the Rapleaf API, I encountered some major issues with SSL on production and staging servers.

Discarding what I did, the application just couldn’t get through to the external service using SSL and kept giving me errors regarding SSL communication.

After reading the Rapleaf gem documentation I found that you should reference your certificate file, this “telling” the service where your certificate file is.

I am working with Amazon EC2 for deployment of my application, both for production and for staging, I had some trouble finding the file, so I executed a *nix command and found the files in no time.

Here’s how you find the file:

[shell]
find / -name ‘*.pem’
[/shell]

Once you find the file, you just create the API instance and refer to it’s path like so:

[ruby]
@api = RapleafApi::Api.new("YOUR_API_KEY", :timeout => 10, :ca_file => "path_to_pem_file")
[/ruby]

Have fun!