Tuesday, December 18, 2012

Friday, November 16, 2012

Check if a dom element has children


$('#foo).children().length > 0

Wednesday, October 31, 2012

Added message to Campfire chatroom for Capistrano deploys


# Gemfile
gem 'capistrano-campfire'
gem 'tinder'

# config/deploy.rb
require 'capistrano/campfire'
require 'tinder'

namespace :campfire do
  desc "Send a message to the campfire chat room"
  task :snitch do
    campfire = Tinder::Campfire.new YOUR_CAMPFIRE_ACCOUNT, :ssl => true, :token => YOUR_CAMPFIRE_TOKEN
    room = campfire.find_room_by_name YOURC_CAMPFIRE_CHATROOM
    snitch_message = fetch(:snitch_message) { ENV['MESSAGE'] || abort('Capfire snitch message is missing. Use set :snitch_message, "Your message"') }
    room.speak(snitch_message)
  end

  desc "Send a message to the campfire chat room about the deploy start"
  task :snitch_begin do
    set :snitch_message, "BEGIN DEPLOY [#{stage.upcase}]: #{ENV['USER']}, #{branch}/#{real_revision[0, 7]} to #{deploy_to}"
    snitch
  end

  desc "Send a message to the campfire chat room about the deploy end"
  task :snitch_end do
    set :snitch_message, "END DEPLOY [#{stage.upcase}]: #{ENV['USER']}, #{branch}/#{real_revision[0, 7]} to #{deploy_to}"
    snitch
  end

  desc "Send a message to the campfire chat roob about the rollback"
  task :snitch_rollback do
    set :snitch_message, "ROLLBACK [#{stage.upcase}]: #{ENV['USER']}, #{latest_revision[0, 7]} to #{previous_revision[0, 7]} on #{deploy_to}"
    snitch
  end
end

before :deploy do
  campfire.snitch_begin unless ENV['QUIET'].to_i > 0
end

after :deploy do
  campfire.snitch_end unless ENV['QUIET'].to_i > 0
end

Permission denied (publickey) error when trying to do cap deploy

My solution was to run in my terminal

ssh-add
Seemed like my there wasn't an identity associated with my ssh public key so Github rejected capistrano attempt to git clone from the deployment server.

Tuesday, October 30, 2012

Top 3 hosted CI (continuous integration) for Rails apps


Here's my summary of top 3 hosted solutions for Rails continuous integration are:

- https://semaphoreapp.com/features
- https://www.circleci.com/
- Tddium

Tddium looks very configurable and gives power to the commandline, eg. run builds from local console on branches. $15/mth for 10 worker hours.

http://docs.tddium.com/

CircleCI had good reviews and sounded like it runs builds really fast. Like Tddium, it's configurable via a yaml file. No official price plans on website but responded via twitter that theirs plans starts from $19.

http://blog.exceptional.io/news/circleci/

Semaphore selling point's their "simple stupid" approach to CI. Oauth via Github, add collaborators and boom. Runs are every git push and at a price of $14/mth, it seemed the cheapest of 'em lot.

https://semaphoreapp.com/features

My vote is for Semaphore since it's the cheapest and simplest to use for a small project.

Thursday, October 25, 2012

Update all associations of a Rails model


  @msg_thread.messages.update_all(status: 'read')

Tuesday, October 16, 2012

Ember.js gotcha - require handlebar.js

Require handlebar.js BEFORE ember.js

# in rails
//= require handlebars
//= require ember

Scope javascript variable in coffeescript so it's available in browser


App = Foo.bar

window.App = App

Rails scaffold only the controller resource


rails g scaffold_controller users

Wednesday, October 3, 2012

Customizing devise views & controllers

I find myself repeating and googling this far too many times...

# Generate the devise views
rails g devise:views

# Add customize views resource to route
devise_for :users, controllers: { registrations: "users/registrations" }

# Move views to new resource folder
git mv app/views/devise/registrations/ app/views/users/

# Add new custom devise controller
class Users::RegistrationsController < Devise::SessionsController

  def new
    @user = User.new
  end

  def create
    ...
  end

end

Cannot customize default devise views

DO NOT use Devise to generate scoped views.

rails generate devise:views users
Just use

rails generate devise:views

Saturday, September 22, 2012

Tuesday, August 28, 2012

Add index on PostgreSQL table column for in-built full text search in Rails

Applicable for PG 8.4 and above.

class AddIndexesToListings < ActiveRecord::Migration
  def change
    execute <<-SQL
      create index on listings using gin(to_tsvector('english', title));
      create index on listings using gin(to_tsvector('english', description));
    SQL
  end
end

Upgrade Heroku db to new PostgreSQL Dev addon


heroku addons:add heroku-postgresql:dev
heroku pg:promote NEW_DB_COLORFUL_NAME

Restarting crashed workers in Heroku

Presumably we can issue the restart command

heroku restart worker.1
But don't bother. It didn't work for me. Just kill it and spin up another worker.

heroku ps:scale worker=0
heroku ps:scale worker=1

Configure PostgreSQL full-text search using pg_search gem for partial word match


class Listing < ActiveRecord::Base
  include PgSearch
  pg_search_scope :search_by_title_and_description, against: [:title, :description], using: { tsearch: { prefix: true } }
end

Monday, August 27, 2012

Run delayed jobs on Heroku with queue names


heroku config:set QUEUE=xxx
heroku ps:scale worker=1

Friday, August 24, 2012

Transfer domain from a Heroku Zerigo account to another


Say you have a domain foo.com that's tied to a Heroku Zerigo addon, you can import them and all its CNAME entries into another account very easily.

Steps:

1. In old Zerigo account, click on domain  >> "Tools" >> "Reassign domain"
2. Click "Generate a reassignment token" button and copy the token string
3. In new Zerigo account, click on "+ add / import" >> "Add reassigned domain"
4. Enter the transferring domain name and the copied reassignment token
5. Click "Add" and voila!

Thursday, August 16, 2012

Share methods between controller and views in Rails

The key is to put methods into ApplicationHelper and call them in the controller

module ApplicationHelper
  def user_unauthorized?
    ...
  end
end

class HomeController < ApplicationController
  def index
    redirect_to '/foo' if view_context.user_unauthorized?
  end
end

Tuesday, August 14, 2012

Passing array of elements as multiple arguments in a ruby method

Suppose we wanna pass an array of elements like this

keys = %w{
  user_id
  shop_id
  url
  title
  shop_name
}

Then we need to prepend the variable with * as arguments

Shop.slice(*keys)

Wednesday, August 8, 2012

Multiple heroku apps on different subdomains managed by Zerigo

Suppose you have 3 different heroku apps but you want them to have their own domains as well as subdomains.

a.herokuapps.com -> a.foo.com or a.com
b.herokuapps.com -> b.foo.com or b.com
c.herokuapps.com -> c.foo.com or c.com
If you wanna use the Zerigo DNS addone, the trick is to use addon in ONLY ONE of the heroku apps. In this instance, I'll add the Zerigo addon into a.herokuapps.com. From the addon dropdown, you should be able to click on the configure button and that'll bring you to the Zerigo admin page. Suppose you've already point the foo.com, a.com, b.com and c.com nameservers to Zerigo nameservers, you should add the subdomains as CNAME entries.

a.foo.com CNAME as a.herokuapps.com
b.foo.com CNAME as b.herokuapps.com
c.foo.com CNAME as c.herokuapps.com
And add all the domains and subdomains as custom domains in each heroku app and should be good to go once the DNS gets propagated.

Friday, July 20, 2012

Speed up updates of large datasets/records in Rails

Suppose we have 10,0000 users. We can do the following

User.find_each |user|
  user.update_attributes(status: 'active')
end
But that takes a long to complete. Executing raw sql over ActiveRecord speeds things up tremendously.

User.connection.execute("update users set status = 'active'")

Monday, July 16, 2012

Get ruby constant from string


UserType.const_get('foo'.upcase)

Rails generator to generate rspec files by default instead of test unit

Just add rspec-rails into the Gemfile. Nothing else needed.

group :development, :test do
  gem 'rspec-rails'
end

Tuesday, June 19, 2012

Sync database from production db on Heroku

One could use the awesome taps gem like so:

heroku db:pull

However that gets real slow real quick so I had to use PG Backups addon instead

# Install heroku addon
heroku addons:add pgbackups

# Capture latest db snapshot on heroku
heroku pgbackups:capture

# Get download url and enter it in browser with a heroku login session
heroku pgbackups:url {latest_backup_name}

# Restore pg dump into local PostgreSQL database
pg_restore -d {db_name} ~/Downloads/{latest_backup_name}.dump

Starting PostgreSQL server on OSX


pg_ctl -D /usr/local/var/postgres start

Thursday, June 14, 2012

Force remove files in OSX Trash


rm ~/.Trash/xxx

Monday, June 11, 2012

Rails number_to_percentage always 0

This is a silly mistake that I often make.

# This always return a big fat zero
number_to_percentage(User.count/Signup.count)

# Remember to have divide by floats!
number_to_percentage(User.count.to_f/Signup.count.to_f)

Check if string is a JSON in Rails


# config/initializers/string_methods.rb

require 'json'

class String
  def is_json?
    begin
      !!JSON.parse(self)
    rescue
      false
    end
  end
end

Friday, June 8, 2012

Switch database from MySQL (ClearDB addon) back to PostgresSQL in Heroku

Had permission problems using ClearDB and figure it wasn't worth all the hassle of adding another layer of abstraction/configuration when Heroku already works with PostgreSQL out of the box. Here's how to switch back to PG.


# Remove addon
heroku addons:remove cleardb

# Set DATABASE_URL back to PG
heroku config | grep SHARED_DATABASE_URL # => postgres://XXX
heroku config:add DATABASE_URL='postgres://XXX'

Wednesday, June 6, 2012

ClearDB MySQL on Heroku gotcha

Didn't know that a rails project deployed on heroku was using ClearDB MySQL as production database - I just assumed that it's PostgreSQL on Heroku till I saw that ClearDB addon was used. Removing the addon and mysql gems and configuring config/database.yml did not saw the application switched back to PG. Read the ClearDB addon and realized that DATABASE_URL environment was set.

https://devcenter.heroku.com/articles/cleardb

Wednesday, May 30, 2012

Quickly checkout Git remote branch into a local branch


git checkout -b LOCAL_BRANCH origin/REMOTE_BRANCH

Friday, May 18, 2012

Codeblocks for Markdown

From Daring Fireball:
To produce a code block in Markdown, simply indent every line of the block by at least 4 spaces
At least 4 spaces... so that means 2 tabs if your tab is set to 2 spaces.

SQL dump for MySQL databases

backup:

mysqldump -u root DATABASE_NAME > sqldump.sql
restore:

mysql -u root DATABASE_NAME < sqldump.sql

Monday, May 7, 2012

Search and replace words in multiple files in Vim

Upgraded my project's factory girl and got some nasty warnings about Factory(:xxx) and Factory.create(:xxx) syntax being deprecated. I've been using the former for almost all of the specs so needed an easy way to search and replace words in multiple files in Vim.

:args app/models/*
:argdo %s/Factory(:/FactoryGirl.create(:/ge | update

Wednesday, March 28, 2012

Differences in Ruby's loading methods

load() - loads and reloads indiscriminately

autoload() - only loads when classes inside are first called upon

require() - loads only once, further calls are ignored

require_relative() - same as require() except file paths are explicitly relative

Tuesday, February 7, 2012

Inverted to negative screen on OSX

Great for presentation when ambient lights are too bright and words can't be seen.

CTRL+OPT+CMD+8

Sunday, February 5, 2012

etc hosts on OSX


sudo vi /private/etc/hosts
or
sudo vi /etc/hosts

Thursday, February 2, 2012

Rspec validate_presence_of matcher with scope

it { should validate_uniqueness_of(:foo).scoped_to(:bar) }

Wednesday, February 1, 2012

Tuesday, January 31, 2012

Show whitespace characters in Vim

This toggles showing the whitespaces

:set list!

Blog Archive