module UsersHelper
# Rails cookbook p 190
def url_for_gravatar(email)
gravatar_id = Digest::MD5.hexdigest( email )
"http://www.gravatar.com/avatar.php?gravatar_id=#{ gravatar_id }"
end
end
gravatar for rails app 1
Useful server terms & commands
Port 80: The port your computer listens on to do http (hyper text transfer protocol). thanks
Daemon: A computer program that runs in the background, rather than under the direct control of a user. It also creates a pid number. wikipedia
PID: process id of a unique process wikipedia
vmstat 4 10 free -m
Manage your mysql production databases on slicehost using CocoaMySQL and tunnel through SSH
Note that if your ssh port is different than the standard 22, your tunnel line will look like this:
If 2020 is my port I created for ssh.
ssh -fNg -L 2020:127.0.0.1:3306 username@123.45.67.89 -p 2020

Deploying your rails app on slicehost with git (github), nginx virtual host, and thin
UPDATE July 13, 2008: see the very bottom for deploy.rb file that includes cron job and namespaces some of the deploy tasks.
–
This article assumes you already have git nginx, and thin setup properly on your slicehost. To get those going I recommend reading their articles at articles.slicehost.com, and browse their forum for git installation.
0. Make sure you server is setup to talk to github. Github has a guide
1. Capify your rails app from inside the root of your app in terminal
capify .
2. Edit the deploy.rb file
# here is a good standard example
set :application, "undertakerapp"
# Change this appropriately depending on what site you are testing
set :domain, "domain.com" # your domain.com for this app
set :user, "username" # your username on slicehost
#from http://github.com/guides/deploying-with-capistrano
default_run_options[:pty] = true
set :repository, "git@github.com:scottmotte/motte_cms.git" # your repository. this could be anywhere, but i recommend github
set :scm, "git"
set :scm_passphrase, "password" #github password
set :user, "username" #github username
set :branch, "master" #this is the branch you want. most likely master
set :deploy_via, :remote_cache
#from hostingrails.com/forums/wiki_thread/46
set :use_sudo, false
set :port, 8000 # your port on slicehost. Standard port for ssh is 22, but if you followed the slicehost articles, you probably changed this to something different
set :deploy_to, "/home/#{user}/public_html/#{application}" # Where on the server your app will be deployed
set :chmod755, "app config db lib public vendor script script/* public/disp*" # Some files that will need proper permissions
# If you aren't deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
# set :deploy_to, "/var/www/#{application}"
# If you aren't using Subversion to manage your source code, specify
# your SCM below:
# set :scm, :subversion
role :app, domain
role :web, domain
role :db, domain, :primary => true
desc "Reload Nginx"
task :reload_nginx do
sudo "/etc/init.d/nginx reload"
end
desc "Restart Thin"
task :restart_thin do
sudo "/etc/init.d/thin restart"
end
after "deploy", "deploy:cleanup"
after "deploy:cleanup", "reload_nginx"
after "reload_nginx", "restart_thin"
3. Fix up your database.yml: make sure the production database settings are specified as follows
production: adapter: mysql encoding: utf8 database: yourapp_production username: mysql_user # the mysql username you are going to use. this could be root, but it probably isn't the best idea to use root password: password # the mysql password you are going to use. socket: /var/run/mysqld/mysqld.sock
4. Setup your database on slicehost: This is easy(er) if you have phpmyadmin. To do it in the terminal do the following.
- ssh into your slicehost
- type mysql -u mysql_user -p (replace mysql_user with your mysql user. this could be root)
- a successful entering should show you the mysql> prompt (mysql>)
- type show databases;
- if it has not been created do
CREATE DATABASE yourapp_production;
5. Exit your server and go back to your local command prompt and cd inside your railsapp. Type the following:
cap deploy:setup # wait for that to complete then... cap deploy:cold # wait for that to complete then you might need to do... cap deploy:migrations # any other changes you commit to github and then want to deploy, you can now just run 'cap deploy' (unless you have new migration files, in which case run 'cap deploy:migrations')
6. Thin configuration:
Follow some of these steps to get thin setup, and your app symlinked
ssh into your slicehost
cd ~/public_html/railsapp/current folder
sudo thin config -C /etc/thin/railsapp.yml -c /home/username/public_html/railsapp/current/ --servers 3 -e production
IMPORTANT NOTE: If you are doing a second app on the same server through vhosts (like so) I’m pretty sure you need to change the default port in the the thin config file. 3000 will already be used by the original one you created.
Therefore, you might do something like this:
sudo thin config -C /etc/thin/railsapp.yml -c /home/username/public_html/railsapp/current/ --servers 3 --port 3001 -e production
check it exists:
cat /etc/thin/railsapp.yml
start it up:
sudo /etc/init.d/thin start
7. Nginx virtual host:
Add your site to the sites available
sudo nano /usr/local/nginx/sites-available/domain.com
Add server vhost and server info (Take your time doing this. There are a lot of places you could mistype things.)
upstream domain1 {
server 127.0.0.1:3003;
server 127.0.0.1:3004;
server 127.0.0.1:3005;
}
server {
listen 80;
server_name www.domain.com;
rewrite ^/(.*) http://domain.com permanent;
}
server {
listen 80;
server_name domain.com;
access_log /home/demo/public_html/railsapp/shared/log/access.log;
error_log /home/demo/public_html/railsapp/shared/log/error.log;
root /home/demo/public_html/railsapp/current/public/;
index index.html;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect false;
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (!-f $request_filename) {
proxy_pass http://domain1;
break;
}
}
}
Now enable it.
sudo ln -s /usr/local/nginx/sites-available/domain.com /usr/local/nginx/sites-enabled/domain.com
8. Now do another of these on your local computer:
cap deploy
UPDATE:
set :application, "mottemen"
# Change this appropriately depending on what site you are testing
set :domain, "mottemanagers.com"
set :user, "***username***"
#from http://github.com/guides/deploying-with-capistrano
default_run_options[:pty] = true
set :repository, "git@github.com:scottmotte/mottemen.git"
set :scm, "git"
set :scm_passphrase, "***password***" #This is your custom users password
set :user, "***username***"
set :branch, "master"
set :deploy_via, :remote_cache
#from hostingrails.com/forums/wiki_thread/46
set :use_sudo, false
set :port, 1984
set :deploy_to, "/home/#{user}/public_html/#{application}" # Where on the server your app will be deployed
set :chmod755, "app config db lib public vendor script script/* public/disp*" # Some files that will need proper permissions
role :app, domain, :cron => true
role :web, domain
role :db, domain, :primary => true
namespace :cron do
task :start, :roles => :app, :only => {:cron => true} do
cron_tab = "#{shared_path}/cron.tab"
run "mkdir -p #{shared_path}/log/cron"
require 'erb'
template = File.read("config/cron.erb")
file = ERB.new(template).result(binding)
put file, cron_tab, :mode => 0644
# merge with the current crontab
# fails with an empty crontab, which is acceptable
run "crontab -l >> #{cron_tab}" rescue nil
# install the new crontab
run "crontab #{cron_tab}"
end
end
namespace :cron do
task :stop, :roles => :app, :only => {:cron => true} do
cron_tmp = "#{shared_path}/cron.old"
cron_tab = "#{shared_path}/cron.tab"
begin
# dump the current cron entries
run "crontab -l > #{cron_tmp}"
# remove any lines that contain the application name
run "awk '{if ($0 !~ /#{application}/) print $0}' " +
"#{cron_tmp} > #{cron_tab}"
# replace the cron entries
run "crontab #{cron_tab}"
rescue
# fails with an empty crontab, which is acceptable
end
# clean up
run "rm -rf #{cron_tmp}"
end
end
namespace :nginx do
desc "Reload Nginx"
task :reload do
sudo "/etc/init.d/nginx reload"
end
end
namespace :thin do
desc "Restart Thin"
task :restart do
sudo "/etc/init.d/thin restart"
end
end
after "deploy", "deploy:cleanup"
after "deploy:cleanup", "nginx:reload"
after "nginx:reload", "thin:restart"
after "thin:restart", "cron:stop"
after "cron:stop", "cron:start"
Mysql command line tricks
I couldn’t get just mysql to work on my slicehost, but if I typed the following i was in:
mysql -u username -p # this will then prompt you for the password
Then I typed help for a list of commands
mysql> help
Then I used some of the commands from my this mysql cheat sheet.
I did:
SHOW DATABASES;
There was only the information_schema table so I created a new one.
CREATE DATABASE db_name;
Then I selected that database to view its internals (nothing is in there of course until I run cap deploy:migrations on my app)
USE db_name;
AJAX paginate with rjs and will_paginate
UPDATE: I actually ended up using this solution because the one below was throwing a javascript error on the page.
# helpers/remote_link_renderer.rb
# from http://weblog.redlinesoftware.com/2008/1/30/willpaginate-and-remote-links
class RemoteLinkRenderer < WillPaginate::LinkRenderer
def page_link_or_span(page, span_class = 'current', text = nil)
text ||= page.to_s
if page and page != current_page
@template.link_to_remote text, :url => url_for(page), :method => :get
else
@template.content_tag :span, text, :class => span_class
end
end
end
# in the controller
def index
@images = Image.paginate :all, :per_page => 15, :page => params[:page], :conditions => ['parent_id is null'], :order => 'id DESC'
respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => @images.to_xml }
format.js do
render :update do |page|
page.replace_html 'images', :partial => "/admin/images/image", :collection => @images
page.replace_html 'will_paginate', "#{will_paginate @images, :renderer => 'RemoteLinkRenderer'}"
end
end
end
end
<%= will_paginate @images, :renderer => 'RemoteLinkRenderer' %>
–
Here is a great tutorial for putting rjs and will_paginate together to ajax paginate things.
However, the new will_paginate uses links differently so you have to add the following to your js block. (Make sure your will_paginate @images is in a div with an id of ‘will_paginate’.
View:
<%= will_paginate @images %>
Addition to js block:
page.replace_html 'will_paginate', "#{will_paginate @images}"
What your js block will look like:
format.js do
render :update do |page|
page.replace_html 'images', :partial => "/admin/images/image", :collection => @images
page.replace_html 'will_paginate', "#{will_paginate @images}"
end
end
strftime, ruby
I always forget these:
%a - The abbreviated weekday name (``Sun'')
%A - The full weekday name (``Sunday'')
%b - The abbreviated month name (``Jan'')
%B - The full month name (``January'')
%c - The preferred local date and time representation
%d - Day of the month (01..31)
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%p - Meridian indicator (``AM'' or ``PM'')
%S - Second of the minute (00..60)
%U - Week number of the current year,
starting with the first Sunday as the first
day of the first week (00..53)
%W - Week number of the current year,
starting with the first Monday as the first
day of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%Z - Time zone name
%% - Literal ``%'' character
t = Time.now
t.strftime("Printed on %m/%d/%Y") #=> "Printed on 04/09/2003"
t.strftime("at %I:%M%p") #=> "at 08:56AM"
Geektool is pretty cool
Just came across Geektool. It’s pretty cool, and a great way to customize your desktop to your super power user needs.

nginx default host
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}