Tuesday, December 18, 2012
Friday, November 16, 2012
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
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
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
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
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
Thursday, June 14, 2012
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
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 spacesAt 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
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
Thursday, February 2, 2012
Rspec validate_presence_of matcher with scope
it { should validate_uniqueness_of(:foo).scoped_to(:bar) }
Wednesday, February 1, 2012
Ruby case switch gotcha
Doh. Ruby's case switch implicitly checks Object#class.
http://www.postal-code.com/mrhappy/blog/2007/02/01/ruby-comparing-an-objects-class-in-a-case-statement/
http://www.postal-code.com/mrhappy/blog/2007/02/01/ruby-comparing-an-objects-class-in-a-case-statement/
Tuesday, January 31, 2012
Subscribe to:
Posts (Atom)
Blog Archive
-
▼
2012
(42)
-
►
October
(9)
- Added message to Campfire chatroom for Capistrano ...
- Permission denied (publickey) error when trying to...
- Top 3 hosted CI (continuous integration) for Rails...
- Update all associations of a Rails model
- Ember.js gotcha - require handlebar.js
- Scope javascript variable in coffeescript so it's ...
- Rails scaffold only the controller resource
- Customizing devise views & controllers
- Cannot customize default devise views
-
►
August
(9)
- Add index on PostgreSQL table column for in-built ...
- Upgrade Heroku db to new PostgreSQL Dev addon
- Restarting crashed workers in Heroku
- Configure PostgreSQL full-text search using pg_sea...
- Run delayed jobs on Heroku with queue names
- Transfer domain from a Heroku Zerigo account to an...
- Share methods between controller and views in Rails
- Passing array of elements as multiple arguments in...
- Multiple heroku apps on different subdomains manag...
-
►
October
(9)