Yesterday I've encountered some strange behavior in Rails 2.1. When I called build on an association that was empty (i.e. customer.orders.build) and then passed that association as a collection to a partial, nothing got displayed. When I called length or each {} on that association right after the call to build, however, it worked. So I sort of needed to "commit" the build call by calling length right after.
I posted it to the Ruby On Rails Core group and it turned out that it was indeed a bug. It had been fixed in edge already, though.
So if you're not using edge, but the actual Rails 2.1 release, make sure to call length (i.e. customer.orders.length) after you call build on an empty association until the fixed version gets released.
Wednesday, August 20, 2008
Found a Bug in Rails 2.1... kinda
Tuesday, July 15, 2008
Check If a Remote File or Directory Exists with Capistrano
I have a Rails app that can have custom logos for different deployments. I wanted to make it easy and simply drop the custom images into a shared/images directory and have Capistrano copy them to current/public/images but only when the shared/images directory exists. Naively I tried this:
if File.directory? "#{shared_path}/images"
run "cp #{shared_path}/images/* #{release_path}/public/images/"
end
Haha, cute. This does not work, since it checks for the LOCAL file, not for the file on the remote machine. Others had a similar problem.
So what's the solution? For me it was to realize that there are other languages besides Ruby to do the job, namely shell scripting. So to conditionally copy files only if a certain directory exists on the remote machine, use this one liner:
# if the shared/images directory exists, copy all images from there to the current/public/images directory
# to replace logos and stuff like that
run "if [[ -d #{shared_path}/images ]]; then cp #{shared_path}/images/* #{release_path}/public/images/; fi"
Enjoy!
Run Your Rails Application Offline Without Slingshot
I just read about a cool project over at the Google Code Blog. Two graduates from NYU have created a Rails plugin called Gears on Rails or acts_as_local. It uses Google Gears for local data storage so you can run your Rails application offline. From the website:
Gears on Rails helps developers to write fully offline functionnal web applications based on Gears without learning a bit of Gears.
That sounds very cool. The website has a demo so you can dive into the code right away. This might be a nice alternative to Slingshot, although Slingshot also hides the Ruby requirements from the user and packages everything up nicely, something Gears On Rails doesn't do. But it shouldn't be too hard to implement a Slingshot clone based on Gears On Rails. We'll see.
Wednesday, July 2, 2008
Rails 2.1 Killed My MySql Foreign Keys

I'm porting a big Rails 1.2.x application to Rails 2.1 at the moment. Everything went smoothly so far, I used the rake deprecated task and watched out for gotchas, and replaced Rails 1.2.x pagination with will_paginate.
When I tried to run my test suite, though, it threw up all over my terminal:
Mysql::Error: #HY000Can't create table './coresales_test/#sql-1702c_b.frm' (errno: 150): ALTER TABLE agents ADD CONSTRAINT agents_ibfk_1 FOREIGN KEY (location_id) REFERENCES locations (id)
It took me a bit to find the solution for this, but alas! I eventually did. To make a long story short: Rails 2.1 doesn't handle integer columns without a :limit attribute correctly by assuming a default limit of 11 and then turning that - not into int(11) - but into bigint(11). Foreign keys have to be of the same data type, though. So MySql rightly complains about it.
The solution? Either use edge rails or use the monkey patch suggested in this extensive blog post about the problem.
This was really quite annoying, but I'm glad that there are nice people out there providing patches and nice write-ups about such problems.
If this was useful for you, please take a minute and recommend me:

Thank you!
Thursday, June 19, 2008
Using Rails gems:build Rake Task with Capistrano
I use acts_as_ferret in my Rails app which depends on the ferret gem. With Rails 2.1 you can define gem dependencies right in your environment.rb file. That's pretty neat. What if your gem needs native extensions to be built? Also easy, just run
rake gems:build
Of course you'd also like these extensions to be built on your production machine when you deploy with Capistrano. I'm sure there are more elegant ways to do this, but this works for me. Just add this to your deploy.rb file:
task :after_update_code, :roles => :app do
if ENV['build_gems'] and ENV['build_gems'] == '1'
run "rake -f #{release_path}/Rakefile gems:build"
end
end
This way you can pass an environment variable to tell Capistrano if you want native gem extensions to be built or not. If you do, call this:
build_gems=1 cap deploy
...and if you don't just call
cap deploy.
I always love to learn about more elegant solutions, so please comment if you know one.
If this was useful for you, please take a minute and recommend me:

Thank you!
Unit Testing with acts_as_ferret

I'm using acts_as_ferret for full text search in a Rails app I'm building. It works great and of course I want to unit test the full text search in my models. So I added an extremely simple test (I have two fixtures that have the matching string "bla" in on of their indexed fields):
def test_find_by_contents
assert_equal 2, MyModel.find_by_contents('bla').total_hits
end
This is great, except for one small problem: it almost always fails! The total_hits are sometimes 1, sometimes 0 and hardly ever 2. Why? Because the data from the fixtures is rebuilt before every test case so ferret can't keep it's index up to date quickly enough.
A very crude but simple solution is to rebuild the index before ferret-related tests:
def test_find_by_contents
MyModel.rebuild_index
assert_equal 2, MyModel.find_by_contents('bla').total_hits
end
Now it works as expected. This will affect performance, though. So if you have a huge test suite, you might want to consider using the preload fixtures plugin from ELC Technologies. I haven't tried this, but it most likely will also eliminate the need to rebuild the index before ferret related tests since the fixtures are not constantly dumped and rebuilt.
If this was useful for you, please take a minute and recommend me:

Thank you!
Thursday, May 29, 2008
Set a Date Attribute from date_select Without Mass Assignment in Ruby On Rails
This has been talked about a million times, but I just ran into this problem again and want to share the solution:
You have a date_select helper in your Rails view and you want to assign the selected date to your model. With mass assignment that's not a problem, but when you try this:
@something.my_date = params[:something][:my_date]
You will be disappointed and there will be wailing and gnashing of teeth. Why? Because date_select creates 3 form components and 3 corresponding values in the form and in the params[:something] hash, namely
params[:something][:my_date(1i)]
params[:something][:my_date(2i)]
params[:something][:my_date(3i)]
These represent the year, the month and the day (Duh!).
When you use @something.attributes= to mass assign this, ActiveRecord takes care of creating a date object from these three values (see attributes=, assign_multiparameter_attributes, extract_callstack_for_multiparameter_attributes, and execute_callstack_for_multiparameter_attributes). Sometimes you might not want to mass assign, though (security comes to mind).
So what are you to do? Maybe putting this code (inspired by this code) in your application.rb might help:
private
def convert_date(hash, date_symbol_or_string)
attribute = date_symbol_or_string.to_s
return Date.new(hash[attribute + '(1i)'].to_i, hash[attribute + '(2i)'].to_i, hash[attribute + '(3i)'].to_i)
end
Now you can assign dates from date_select like this:
@something.my_date = convert_date(params[:something], :my_date)
Please comment if you have a better or more elegant solution!
If this was useful for you, please take a minute and recommend me:

Thank you!
Tuesday, May 27, 2008
Rails Time Travel: Manipulating Time.now for Tests
Can we go anywhere we want at any time?
You can do anything you want.
Do you have code in your Ruby on Rails models that depends on the current date and time? I do. And I want to test it to make sure it works right. In my case a certain date is only valid if it is in the current month or in the previous month but only if it's not the 11th day of the month yet. If today were the 10th of May - for example - a date in April would be valid. If today were the 11th of May, a date in April wouldn't be valid anymore, though.Just testing this piece of code if the day the tests are being run happens to be below the 11th day of the month is not a solution, of course. So I googled a bit and found this wonderful piece of code.
These are the steps to get your Rails Time Machine (tm) up and running:
- Copy the above code to a file and save it as test/time_helper.rb
- Require it in your test:
require File.dirname(__FILE__) + '/../time_helper'
- Either set the time for all the tests in the file:
def setup
pretend_now_is(Time.local(2007, 8, 1)) # position *all* tests back in time!
end
def teardown
Time.reset # jump back to the present
end
or just do some time travel for a code block:
(These code samples come from here. Thank you!)
def test_decades
pretend_now_is(Time.local(1960)) do
assert_equal(1960, Time.now.year)
end
pretend_now_is(Time.local(1970)) do
assert_equal(1970, Time.now.year)
end
# ...
end - Find a street where your De Lorean can reach 88 mph and run your time traveling tests!
If this was useful for you, please take a minute and recommend me:

Thank you!
Monday, May 5, 2008
Setting up attachment_fu for Rails with ImageScience on a Mac

Who doesn't need file uploads in their Rails app? Lots of people, but I'm unfortunately not one of them. No need to reinvent the wheel, though since there's a spiffy plugin called attachment_fu by Rails core contributor Rick Olsen aka techno weenie.
How to set this sucker up on Mac OS? Easy:
Update:Digging through the source of the attachment_fu plugin I found something very cool that's not mentioned in the README: it comes with a CoreImage image processor. So if you use a current version of Mac OS X you can skip straight to step 7. Attachment_fu will find CoreImage on it's own. If not, just supply :core_image as the :processor parameter for has_attachment.
- Install MacPorts by following the instructions. A .profile should be created by the install script. It didn't feel like doing that on my system, so I created a .profile file in my home directory with this contents:
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
export MANPATH=/opt/local/share/man:$MANPATH - Restart Terminal.app
- Update the MacPorts ports:
sudo port selfupdate - Install FreeImage:
sudo port install freeimage - Install RubyInline:
sudo gem install RubyInline - Install the ImageScience gem:
sudo gem install -y image_science - Finally install the attachment_fu plugin (run this in your Rails project directory):
script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/
That's it. Thanks to Mike Clark for his informative blog post.
What next? Read above mentioned informative blog post to learn how to use attachment_fu in your app or read this Advanced Rails Recipe (PDF) on the topic.
Q&A
Q: Why did you use attachment_fu and not one of the other file upload plugins?
A: Because (1) Rick Olsen knows what he is doing, (2) is a Rails core contributor and (3) has a proven record of great plugins. Oh, and because attachment_fu seems to (4) be actively maintained and (5) supports file system, database and even Amazon S3 data stores.
Q: Why did you choose FreeImage and ImageScience and not ImageMagick and RMagick or MiniMagick?
A: Especially RMagick has the reputation of being a leaking memory hog. I haven't tried it myself, but ImageScience and FreeImage seem to be a lean choice and they do a great job.
If this was useful for you, please take a minute and recommend me:

Thank you!
Thursday, April 24, 2008
The Future for Rails Developers
I just listened to an interesting podcast interview with Tom Mornini, the CTO of Engine Yard. In it he talks a bit about what his company does and the challenges of scalable Rails deployment, but the bit I found especially interesting is what he had to say about Rails developers. He said that there is a huge demand for them and that new developers can't be taught quickly enough to fill that need. He says that it's going to be a multi year process to teach enough developers to satisfy the demand the market has for them.
I guess that puts us Rails developers in a cozy position :)
Wednesday, April 23, 2008
Schritt für Schritt Anleitung: Ruby On Rails Deployment mit Capistrano, Mongrel, Apache, Subversion und Dir
Note to English speaking readers: I've written this tutorial in German because there are a lot of good Rails deployment tutorials out there in English, but not so many in German. If enough people email me or comment and say they want this in English I might translate it ;-).
So, jetzt auf Deutsch: Du willst deine grossartige nagelneu programmierte Ruby On Rails Anwendung fuer die Welt (oder immerhin fuer deinem Kunden) nutzbar machen. Dann will ich dich nicht aufhalten und dir in 27 einfachen Schritten zeigen, wie es geht. Dann wollen wir mal...
- Log dich mit ssh in den Server ein, auf dem die Rails Applikation laufen soll.
- Wenn du dich nicht als root angemeldet hast, werde jetzt root (su -)
- Stell sicher, dass ein Editor wie vi richtig funktioniert. Wenn man von Mac OS X auf einen Linux Rechner geht kann es manchmal Probleme geben. Auf Debian Systemen schafft da oft
apt-get install ncurses-term
Abhilfe. - Aktualisiere die verfuegbaren Pakete:
apt-get update - Installiere folgende Pakete:
apt-get install mysql-server
apt-get install ruby
apt-get install ruby1.8-dev
apt-get install rubygems
apt-get install subversion
apt-get install make
apt-get install build-essential
apt-get install curl
apt-get install apache2 - Installiere folgende Ruby Gems:
gem install --include-dependencies rails
gem install --include-dependencies capistrano
gem install --include-dependencies mongrel (jeweils die neuste ruby version nehmen)
gem install --include-dependencies mongrel_cluster - Gehe nochmal sicher, dass alles aktuell ist:
gem update --system
Wenn du irgendwo den Fehler/usr/bin/gem:23: uninitialized constant Gem::GemRunner (NameError)
bekommst ist das damit zu loesen, folgende Zeile in /usr/bin/gem einzufuegen:require 'rubygems/gem_runner'
Und um den Fehlerundefined method `require_gem' for main:Object
spaeter beim Deployment zu vermeiden solltest du nochmalgem install --remote rake
ausfuehren. Wenn das nicht hilft, in /var/lib/gems/1.8/bin/rakerequire_gem 'rake', version
in
gem 'rake', version
abaendern. - Jetzt musst du die Datenbank einrichten. Wir nehmen hier MySQL und der Einfachheit halber nenne ich in dieser Anleitung die Datenbank, den Datenbank Benutzer und die Rails-Anwendung "springenwerk".
Root Passwort setzen:
mysqladmin -u root password ein_passwort_meiner_wahl
(danach am besten die bash_history loeschen) Dann die Datenbank anlegen und die Berechtigung setzen:
mysql -u root -p
CREATE DATABASE springenwerk;
GRANT ALL PRIVILEGES ON springenwerk.* TO 'springenwerk'@'localhost' IDENTIFIED BY 'ein_password_meiner_wahl' WITH GRANT OPTION;
Die Angaben fuer die Produktions-Datenbank (Name, Username und Passwort) muessen den Angaben in der app/config/database.yml Datei der Rails Anwendung entsprechen.
Jetzt kannst du den Mysql Client mit 'exit' verlassen. - Die ausfuehrbaren Ruby Gems willst du jetzt natuerlich gerne in deinem Pfad haben. Also
in der /etc/profile
/var/lib/gems/1.8/bin
an die PATH Variable haengen. Das kann man so machen:
PATH=$PATH:/var/lib/gems/1.8/bin
Du musst nur aufpassen, dass die das vor die Zeile "export PATH" schreibst. - Dann die Aenderungen in der aktuellen Session nutzbar machen:
source /etc/profile
Wenn du dannrails -v
ausfuehren kannst hat alles geklappt. - Jetzt solltest du einen eigenen User fuer deine Rails Anwendung anlegen:
useradd -m springenwerk
und das Passwort setzten:
passwd springenwerk
Und ihn zu den sudoers packen:
visudo
und dann unten folgende Zeile hinzufuegen (natuerlich "springenwerk" wieder mit deinem Produktions-Usernamen ersetzen):
springenwerk ALL=(ALL) ALL - Da sich Capistrano per SSH einloggt aber auch ein gewisse Benutzerumgebung braucht (z.B. den PATH) musst du in die /etc/ssh/sshd_config folgende Zeilen einfuegen:
# for capistrano
PermitUserEnvironment yes - Dann SSHD neu starten:
/etc/init.d/ssh restart - In /home/springenwerk/.ssh/environment (ggf. ".ssh" Verzeichnis und Datei anlegen) folgende Zeilen einfuegen:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/var/lib/gems/1.8/bin
RUBYOPT=rubygems - Jetzt musst du auf dem CLIENT Capistrano und Mongrel Cluster installieren (ich gehe davon aus, dass Ruby und Rails schon installiert sind)
sudo gem install capistrano
sudo gem install capistrano-ext
sudo gem install mongrel_cluster
Ab Mac OS X Leopard ist capistrano schon dabei, aber stelle mit
sicher, dass du mindestens Version 2.1 hast.
sudo gem update capistrano - Wechsle in dein Rails Projekt Verzeichnis:
cd /Users/johannes/Code/springenwerk/trunk/springenwerk - Jetzt erstellst du eine Konfigurationsdatei fuer den Mongrel Cluster:
mongrel_rails cluster::configure -e production -p 8000 -a 127.0.0.1 -N 2 -c /home/springenwerk/springenwerk/current
-p 8000 sagt, dass die Server ab Port 8000 lauschen, -N 2 sagt, dass es zwei Instanzen geben wird (also eine auf Port 8000, eine auf 8001) und mit -c gibt man das Verzeichnis an, wo auf dem PRODUKTIONSSERVER die Applikation liegen wird (in diesem Fall ein Unterverzeichnis, das so heisst wie die Applikation im Home-Verzeichnis des Users, den wir angelegt haben (welcher auch so heisst wie die Applikation) und mit dem Zusatz "current". Das musst da stehen, denn das
ist ein Symlink, den Capistrano anlegt und der immer auf die aktuelle Version zeigt. - Jetzt musst du dein Rails Projekt capistranofizieren ;-). Wechsle in dein Rails Projekt Verzeichnis:
cd /Users/johannes/Code/springenwerk/trunk/springenwerk
und fuehre capify aus:
capify . - Oeffne jetzt config/deploy.rb in deinem Editor und passe die Datei so an, dass sie so aussieht (mit deinen User- und Projektnamen und Passwoertern natuerlich):
require 'mongrel_cluster/recipes'
default_run_options[:pty] = true # to make sure password prompts are forwarded to you, the user
set :application, "springenwerk"
set :repository_url, "svn://DEIN_SVN_USER@DEIN_SVN_SERVER/springenwerk/trunk/springenwerk"
if ENV['svn_prompt'] and ENV['svn_prompt'] == '1'
set :svn_user, Proc.new { Capistrano::CLI.password_prompt('SVN User: ') }
set :svn_password, Proc.new { Capistrano::CLI.password_prompt('SVN Password: ') }
set :repository, Proc.new { "--username #{svn_user} --password #{svn_password} #{repository_url}" }
else
set :repository, repository_url
end
set :deploy_to, "/home/#{application}/#{application}" # defaults to "/u/apps/#{application}"
set :deploy_via, "export"
set :user, application # in our case, the user and the application have the same name.
set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"
role :app, "DEIN_PRODUCTION_SERVER"
role :web, "DEIN_PRODUCTION_SERVER"
role :db, "DEIN_PRODUCTION_SERVER", :primary => true
# Task to copy production db config after deployment
task :after_update_code, :roles => :app do
db_config = "#{shared_path}/config/database.yml.production"
run "cp #{db_config} #{release_path}/config/database.yml"
end
Die Datei werde ich hier nicht gross erklaeren, dazu gibt es andere Stellen.
Diese deploy.rb Datei hat aber eine kleine Besonderheit (Danke an Jonathan).
Da Subversion natuerlich einen Benutzernamen und ein Passwort erwartet wird normalerweise empfohlen, einmal irgendwo auf dem Produktionsserver das Rails Projekt auszuchecken, damit die Credentials gecachet werden und Capistrano nicht mehr nach SVN Benutzernamen und Passwort fragt. Das koennen wir uns jetzt sparen.
Wir koennen naemlich jetzt angeben, dass Capistrano uns beim ersten Mal einfach nach den Zugangsdaten fuer SVN fragt. Dazu gleich mehr. - Jetzt kann Capistrano die Verzeichnisse auf dem Produktionsserver anlegen. Auf deinem CLIENT fuehre folgendes aus:
cap deploy:setup - Stelle die neuen Konfigurationsdateien unter Versionskontrolle und checke sie ein:
svn add Capfile config/mongrel_cluster.yml config/deploy.rb
svn ci -m "capistrano config" - Du willst aus Sicherheitsgruenden deine Produktionsdatenbank Passwoerter nicht ins SVN einchecken. Deshalb solltest du eine Datei namens database.yml.production anlegen, die die
Zugangsdaten fuer deine Produktionsdatenbank enthaelt. Unser "after_update_code" Task in deploy.rb erwartet diese Datei und kopiert sie dann ueber die ausgecheckte database.yml. Zum Beispiel koennte sie so aussehen:
development:
adapter: mysql
database: springenwerk_development
username: root
password: root
host: localhost
socket: /Applications/MAMP/tmp/mysql/mysql.sock
# Warning: The database defined as 'test' will be erased and
# re-generated from your development database when you run 'rake'.
# Do not set this db to the same as development or production.
test:
adapter: mysql
database: springenwerk_test
username: root
password: root
host: localhost
production:
adapter: mysql
database: springenwerk
username: springenwerk
password: DEIN_PASSWORT
host: localhost
socket: /var/run/mysqld/mysqld.sock
Diese packst du auf dem Produktionsserver in folgendes Verzeichnis:
Das config Verzeichnis musst du vorher anlegen.
/home/springenwerk/springenwerk/shared/config - Jetzt kannst du mit Capistrano von deinem CLIENT ein Erst-Deployment (cold deployment) durchfuehren (in deinem Rails Projektverzeichnis)
"svn_prompt" ist einen Umgebungsvariable, die unserem deploy.rb Skript sagt, dass es nach den SVN Zugangsdaten fragen soll. Denke daran, dass wenn Capistrano dich nach dem Passwort fuer deinen Produktionsserver fragt das Passwort fuer den nicht-root User (in diesem Beispiel "springenwerk") fragt!
svn_prompt=1 cap deploy:cold
Achte darauf, dass es keine Fehler gibt, am Ende sollte
stehen.
command finished - Pruefe auf dem SERVER, ob die Mongrel Dienste laufen:
Wenn Mongrel laeuft, sollte die Ausgabe ungefaehr so aussehen:
curl -I http://127.0.0.1:8000
HTTP/1.1 302 Moved Temporarily
Connection: close
Date: Wed, 06 Feb 2008 11:42:33 GMT
Set-Cookie: _springenwerk_session_id=f4a9b408f36d0df7561fd778e46d2c62; path=/
Status: 302 Found
Location: http://127.0.0.1:8000/session/new
Cache-Control: no-cache
Server: Mongrel 1.1.3
Content-Type: text/html; charset=utf-8
Content-Length: 101
Sehr gut. Jetzt musst du nur noch Apache als Loadbalancer einrichten. Ein Kinderspiel ;-) - Ok, Apache. Bevor du die folgenden Sachen machst, ein kleiner Disclaimer: ich bin kein Apache-Config-Profi. Es kann gut sein, dass es elegantere Wege gibt, das gute Stueck zu konfigurieren. Alle Hinweise die zur Ergreifung des Taeters fuehren werden sehr geschaetzt.
Ans Ende von /etc/apache2/apache2.conf folgendes anfuegen (im vi mit G ans Ende der Datei springen):
Der Inhalt der /etc/apache2/sites-available/000-default Datei muss so aussehen (ich gehe in dem Beispiel davon aus, dass der Apache nur fuer deine Rails Anwendung benutzt wird):
<Proxy balancer://mongrel_cluster>
BalancerMember http://127.0.0.1:8000
BalancerMember http://127.0.0.1:8001
</Proxy>
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /home/springenwerk/springenwerk/current/public
<Directory /home/springenwerk/springenwerk/current/public>
Options FollowSymLinks
AllowOverride None
Order allow,deny
allow from all
</Directory>
RewriteEngine On
RewriteLog /var/log/apache2/rewrite.log
RewriteLogLevel 9
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [L]
RewriteRule ^/$ /index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L]
ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/access.log combined
ServerSignature Off
</VirtualHost> - Dann musst du in /etc/apache2/mods-enabled folgende Symlinks anlegen:
ln -s ../mods-available/proxy_balancer.load
ln -s ../mods-available/proxy.conf
ln -s ../mods-available/proxy_http.load
ln -s ../mods-available/proxy.load
ln -s ../mods-available/rewrite.load
Der Inhalt der proxy.conf muss so aussehen:
<IfModule mod_proxy.c>
#turning ProxyRequests on and allowing proxying from all may allow
#spammers to use your proxy to send email.
ProxyRequests Off
<Proxy *>
AddDefaultCharset off
Order allow,deny
Allow from all
</Proxy>
# Enable/disable the handling of HTTP/1.1 "Via:" headers.
# ("Full" adds the server version; "Block" removes all outgoing Via: headers)
# Set to one of: Off | On | Full | Block
ProxyVia On
</IfModule> - Dann nur noch Apache neu starten:
/etc/init.d/apache2 restart - Feierabend. Das wars.
Wenn du jetzt eine neue Version deiner Anwendung live stellen willst, musst du nur in deinem Rails Projektverzeichnis
cap deploy
bzw
cap deploy:migrations
ausfuehren wenn es neue Datenbankmigrationen gibt. Capistrano macht dann den Rest!
Bitte benutze die Kommentarfunktion wenn du beim Folgen dieser Schritte ein paar Tipps oder Probleme gefunden hast.
Grosser Dank gilt noch dem grossartigen Tutorial von Coda. Da gibt es noch sehr viel Hintergrundinfos. Ich wollte das hier nicht alles wiederholen, sondern es eher kurz und knapp halten. Ich hoffe, dass es ganz hilfreich ist.
Wenn das der Fall ist würde ich mich sehr über eine Empfehlung freuen:

Danke!
Friday, April 11, 2008
My Experience as a Rails Coach
It's Thursday night and I'm typing this at the Munich airport waiting for my flight to Hamburg. I've spent the last 3 days in Bavaria helping two talented PHP developers getting started with Ruby on Rails. It was fun.
On the first day I gave a brief introduction to OOP and TDD along with a quick Rails overview. Then we started coding. We set up Subversion, and coded two demo projects by noon, touching on RESTful design and scaffolding, migrations, MVC, tests, and the joy of having ActiveRecord do all the dirty CRUD work. One of the developers then told me that they were very sceptic at first as to why Rails would improve or speed up their development in comparison to PHP. But those few hours already had convinced him why. That was a very satisfying experience.
On the second day the same developer had the idea of following through the Depot application demo from the AWDWR book and recording what I do as a screencast. That was a great idea. So we started with the Depot application from scratch, using the new Rails 2.0 way of doing things where necessary or where it made sense. We got to the end of Task C on page 109 on the first day and finished the complete Depot application today with testing and all.
So in 3 days we covered A LOT of ground and I have screencasts of developing the whole Depot application with Rails 2. They are pretty raw and they are in German, but they might be helpful to some (if you don't mind my stinking slow iBook and my lame jokes along the way). I'm thinking about making them available on my blog soon.
Well, the bottom line is Rails is great and in 3 days you can give a great introduction to this framework with quite a bit of in-depth information.
Tuesday, March 4, 2008
Developing Ruby on Rails on Mac OS X Leopard, or DRoRoMOSXL
I just received the new ADC newsletter and it had a link to a very nice tutorial for developing Ruby on Rails
applications on Leopard. There are heaps of RoR tutorials out there, but in my experience tutorials written by the Apple folks are of an above average quality.
Another interesting thing about this tutorial is that it uses XCode 3.0 instead of my (and I guess most people's) Mac text editor of choice, TextMate. It's the first of three parts. So to whom it may concern, it might be an interesting read.
Friday, November 2, 2007
Rails, Capistrano and svn+ssh agent forwarding
I was working on deploying a Rails application using Capistrano today. I ran into a few problems because my SVN server uses svn+ssh authentication. I will not go into all the details of using Mongrel and Capistrano, I'll just touch on the points that are important for using it with svn+ssh.
The problem is this: Capistrano logs in to your deployment server and wants to check out your Rails project from your SVN server. If that SVN server uses svn+ssh authentication, you need to enter a password, but since Capistrano is issuing the command, you can't enter that password and everything fails. You'll see something like this:
** [out :: 192.168.0.200] subversion is asking for a password
The solution I used was to use SSH public key authentication instead. Here's a great tutorial.
Once that's done, you only need your private key on your client and the public key on your SVN server.
Now you either keep following the tutorial to set up ssh agent forwarding or you take the easy way and download SSHKeychain for your Mac.
Install it using these instructions (don't forget to enable "Manage global environment variables" in SSHKeychain's Preferences), add it to your Mac's Login Items, log out of your Mac session, and log in again.
If everything with the keys is set up correctly, you should be able to log in to your SVN server through Terminal.app without being asked for a password.
Ok, now you have to tell Capistrano that it should use ssh agent forwarding. That is required for Capistrano to be able to log in to your SVN server using your key and not requiring a password.
So open up deploy.rb and add this line to the SSH OPTIONS section:
ssh_options[:forward_agent] = true
If cap cold_deploy works now: great. In my case, it threw a strange exception like this one:
Net::SSH::Transport::Session: [:forward_agent] (ArgumentError)
That means your net-ssh ruby gem is too old. I think it has to be at least version 1.1.1. So after running
gem update net-ssh
cap cold_deploy worked like a charm!
This great tutorial also helped me a lot.

