The simplest Enum you will ever find for your ActiveRecord models

I have been using a really useful snippet for a while now.

While dropping it today into a project I realized just how powerful it is:

  1. it’s a drop-in and will work on any project
  2. it’s database agnostic
  3. it’s dead simple
  4. it’s not sensitive to enum changes
  5. and more and more

Just as an into, an enum is a way to have string represented as integers in your database.

Why?

Because integers are much faster to index and query (at least on mysql).

MySQL has an enum solution but ActiveRecord can’t really use it without some nasty hacking and it’s really messy when you want to add another param.

Enough Said, here’s the snippet

This gives you the ability to work with the Account model like so:

As you can see, it’s being persisted into the database as an integer, but you work with symbols/strings which is much nicer and cleaner.

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.

Pull Request #5340: Added wrapper tag for simple format, added test by KensoDev · rails/rails

Following my latest post about the simple_format, I think that it’s broken to assume only “p” tags are valid wrappers.

So, I opened a pull request to Rails itself.

Basically, it changes simple_format so you can pass in the wrapper tag you want, I found myself wanting a “div” or a “span” too many times.

Pull Request #5340: Added wrapper tag for simple format, added test by KensoDev · rails/rails.

Enjoy!

Setup your laptop for Ruby and Rails development

Setting up a new machine has never been an easy task, I remember back in the days where I was a windows user, setting up a new machine was a real pain in the ass.

I used to write everything I had installed on a piece of paper and then go one by one and install everything, if I needed to download it could take even days to get a new machine up to speed.

Today I am a Mac user (Thank god), so installing a new machine for myself is the easiest, I simply restore it from a time machine, and I am ready to go in a matter of minutes (well, maybe more, because the data can take quite some GB’s)

At Gogobot, we have new developers coming in (Yeah, we are growing), they all get a brand new Mac machine and they need to get it up and running, this is a common thing, since many developer buy new machines and they want the environment for Ruby, Rails, RVM and the rest of the stack be ready for them, no hassle.

When I came in to Gogobot, we were still running on rails 2 with no bundler, so this was a bigger pain, but today, we are on rails 3 and we have bundler which certainly makes the process easier, but still, not as easy as I wanted it to be.

Our development environment uses almost across the stack technologies, we use mysql of course, we use Redis, memcached, Resque, SOLR and many more, so installing everything can take a long time.

We wanted to take this pain away, enabling new developers (and of course all of the community) to get their machines up and running in a matter of minutes with no interruption for the developer. So, while the developer is doing his tour around the system, his machine will be ready for him when he gets back.

(B.T.W, I keep saying him, but I am referring to female developers as well, don’t get me wrong here ha…)

Last week, I got me a brand new machine, and I could not access my time machine (I was out of my house).

So, I said this is a good opportunity to do what I wanted to do in ages now and get this script up and running.

I cheated

I started with a script Thoughbot had released, I tweaked it and twisted it to fit our needs.

I got my new machine up and running with our project in about 20 minutes, that was amazing and it certainly breaks a Gogobot record.

So, as I always do when I have something half decent, I released it as open source.

You can find it here

Please feel free to use it, if you are having any issues, open an issue in the repo and I will try to address it.

Keep in mind the script is provided AS IS.

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!

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!