<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Foliosus &#187; Ruby on Rails</title>
	<atom:link href="http://www.foliosus.com/category/web-technology/ruby-on-rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.foliosus.com</link>
	<description>Plants, food and web design</description>
	<pubDate>Mon, 05 May 2008 23:27:50 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Connecting Ruby on Rails to Oracle on an Intel Mac in Leopard, take 2</title>
		<link>http://www.foliosus.com/2008/05/05/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-take-2/</link>
		<comments>http://www.foliosus.com/2008/05/05/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-take-2/#comments</comments>
		<pubDate>Mon, 05 May 2008 23:24:31 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/?p=99</guid>
		<description><![CDATA[Since I posted the first version of this article, there have been a couple of changes.  The biggest one is that Intel has released Intel Mac versions of the InstantClient.  Woohoo!  That makes the previous version rather too complicated, so I&#8217;ve updated it here.  This tutorial assumes that you&#8217;re using Rails [...]]]></description>
			<content:encoded><![CDATA[<p>Since I posted the first version of this article, there have been a couple of changes.  The biggest one is that Intel has released Intel Mac versions of the InstantClient.  Woohoo!  That makes the previous version rather too complicated, so I&#8217;ve updated it here.  This tutorial assumes that you&#8217;re using Rails 2.0 or greater.  If you&#8217;re starting from the setup we had before, and you want to fix it, <a href="#fat_fix" title="Jump to the fixer-upper instructions">start with the cleanup instructions at the bottom</a>, and then come back here. <span id="more-99"></span></p>
<h2 id="get_oracle">Grab the new Oracle InstantClient libraries</h2>
<p>The new Intel Mac versions are available from the <a href="http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/intel_macsoft.html" title="Get the libraries: login required">Oracle downloads site</a>.  Install them in <code>/Library/Oracle/</code>.  You can do side-by-side installations in folders with whatever names you want, since apps find them by using the <code>$ORACLE_HOME</code> environment variable (and it&#8217;s friends). I&#8217;ve got mine in <code>/Library/Oracle/instantclient/10.2.0.4</code>.  Also make sure that you&#8217;ve got the files required to run sqlplus and the sdk.  You can drop those in the same directory.</p>
<p>Oh, and don&#8217;t forget to copy over your <code>tnsnames.ora</code> file.</p>
<h3>Symlink the libraries</h3>
<p>In the directory where you&#8217;ve installed the instant client, run this:</p>
<pre class="code">ln -s libclntsh.dylib.10.1 libclntsh.dylib</pre>
<h3>Set the environment variables correctly</h3>
<p>You&#8217;ll probably want to put these lines in your <code>.bash_profile</code>, but they also must be run (or <code>source</code>&#8216;d) from the command line to take effect:</p>
<pre class="code">export ORACLE_HOME=/Library/Oracle/instantclient/10.2.0.4
export TNS_ADMIN=$ORACLE_HOME
export LD_LIBRARY_PATH=$ORACLE_HOME
export DYLD_LIBRARY_PATH=$ORACLE_HOME
export PATH=$PATH:$ORACLE_HOME
</pre>
<p>On to the next step, making Rails &#038; Oracle play nice.</p>
<h2>Getting Rails to talk to Oracle</h2>
<p>First,</p>
<pre class="code">sudo gem install activerecord-oracle-adapter --source http://gems.rubyonrails.org</pre>
<p>This installs the oracle adapter, which is how ActiveRecord deals with Oracle.  It doesn&#8217;t, however, install the Ruby oci8 driver, which is how Ruby talks to Oracle.  We&#8217;ll do that now.</p>
<h3>Compile the ruby-oci8 library</h3>
<p>Make sure you’ve got the <a title="Download the Oracle Instant Client SDK" href="http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/intel_macsoft.html">Oracle Instant Client SDK</a> installed in your Oracle Instant Client directory (/Library/Oracle/instantclient/10.2.0.4)</p>
<p>The most recent stable version of the oci8 library is <a title="Ruby oci8 library" href="http://rubyforge.org/projects/ruby-oci8/">1.0.1</a>.  Download it and unpack the file in the finder: it should unzip into <code>~/Downloads/ruby-oci8-1.0.1</code>.</p>
<p>Now we can finish configuring the environment before we compile the library.</p>
<pre class="code">cd ~/Downloads/ruby-oci8-1.0.0
export SQLPATH=$ORACLE_HOME
export RC_ARCHS=i386
ruby setup.rb config
make
sudo make install</pre>
<p>These steps should cause some compiler output to scroll by.  Pay attention if you run into any errors on the setup step; the error messages are reasonably helpful at pointing you towards any problems.</p>
<h2>Test connectivity</h2>
<p>At this point, we&#8217;re done.  We&#8217;ve got the latest Oracle InstantClient, and we&#8217;ve installed the ruby-oci8 library.  Now it&#8217;s a question of making sure that everything works as advertised:</p>
<pre class="code">ruby /usr/bin/irb</pre>
<p>In the IRb console, type:</p>
<pre class="code">require 'oci8'</pre>
<p>If the console returns <code>true</code> or <code>[]</code>, you’re in business.</p>
<h2>Configure your database.yml</h2>
<p>The last step is to make your application use the Oracle connection.  In your <code>database.yml</code>, use the following to make it work:</p>
<pre class="code">development:
adapter: oracle
database: your_instance_name
username: your_user_name
password: your_password</pre>
<p>The database name comes straight out of your <code>tnsnames.ora</code> file.  You don&#8217;t need to specify any other connection information in <code>database.yml</code>, since the <code>tnsnames.ora</code> file has everything you need.</p>
<p>Your application is now talking to Oracle, without Rosetta!</p>
<h2 id="fat_fix">Fix the <code>ruby_fat</code> and <code>ruby_ppc</code> setup</h2>
<p>If you followed my <a href="/2007/11/19/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-mac-osx-105/" title="Don't read these: you don't want them anymore">previous instructions</a> and went through all of the shenanigans with the <code>ruby_ppc</code> and <code>ruby_fat</code> versions and would like to undo them, it&#8217;s quite simple.  Just remove the <code>ruby_ppc</code> files, and the symlinks to them (called <code>ruby</code>, and rename <code>ruby_fat</code> as <code>ruby</code>:</p>
<pre class="code">cd /usr/bin
sudo rm ruby
sudo rm ruby_ppc
sudo mv ruby_fat ruby
cd /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin
sudo rm ruby
sudo rm ruby_ppc
sudo mv ruby_fat ruby</pre>
<p>Then, you should also remove the 2 management scripts:</p>
<pre class="code">sudo rm /usr/bin/ppc_ruby.sh
sudo rm /usr/bin/fat_ruby.sh</pre>
<p>And that&#8217;s enough for the cleanup.  From here you can start following the instructions beginning with <a href="#get_oracle" title="Start from the top">getting the new Oracle libraries.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2008/05/05/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-take-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HOWTO monkeypatch Rake: overriding a Rake task</title>
		<link>http://www.foliosus.com/2008/05/05/howto-monkeypatch-rake-overriding-a-rake-task/</link>
		<comments>http://www.foliosus.com/2008/05/05/howto-monkeypatch-rake-overriding-a-rake-task/#comments</comments>
		<pubDate>Mon, 05 May 2008 16:33:49 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/?p=98</guid>
		<description><![CDATA[I know that some people really don&#8217;t like monkeypatching, and I see why.  But sometimes it&#8217;s just unavoidable.  Recently at work we came across a situation where the standard rake db:schema:dump task just wasn&#8217;t working. So I started by writing the new version of the rake task that I wanted:
namespace :db do
  [...]]]></description>
			<content:encoded><![CDATA[<p>I know that some people really don&#8217;t like monkeypatching, and I see why.  But sometimes it&#8217;s just unavoidable.  Recently at work we came across a situation where the standard <code>rake db:schema:dump</code> task just wasn&#8217;t working. So I started by writing the new version of the rake task that I wanted:</p>
<pre class="code">namespace :db do
  namespace :schema do
    desc "Create a db/schema.rb file"
    task :dump => :environment do
      require 'active_record/schema_dumper'
      puts "Creating schema:"
      File.open(ENV['SCHEMA'] || &#8220;db/schema.rb&#8221;, &#8220;w&#8221;) do |file|
        ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
      end
    end
  end
end</pre>
<p>This task as shown does exactly what the default rake task does, except for the <code>puts</code> line.  Let&#8217;s just pretend that it&#8217;s a radically different and wonderful version that solves world hunger and raises your children. Now, if you drop this into a rakefile in your app&#8217;s <code>lib/tasks</code> directory, and then you run <code>rake db:schema:dump --trace</code> you&#8217;ll notice that the schema.rb file gets created <strong>twice</strong>.  What the??? <span id="more-98"></span></p>
<h3>Check the docs</h3>
<p>So I started poking around the <a href="http://rake.rubyforge.org/" title="Read the RDocs for Rake">Rake docs</a>. <code>Rake::Task.define_task</code> does the following:</p>
<blockquote><p>Define a task given args and an option block. If a rule with the given name already exists, the prerequisites and actions are added to the existing task. Returns the defined task.</p></blockquote>
<p>Aha!  So instead of overriding the existing task (monkeypatching it), I&#8217;m adding to it.  That&#8217;s why the schema gets dumped twice.  But what if I don&#8217;t want that?  What to do if I want to replace the rake task with my new version?</p>
<h3>Check the internets</h3>
<p>About an hour of googling later, I finally came across <a href="http://matthewbass.com/2007/03/07/overriding-existing-rake-tasks/" title="The solution to my rake problems!">a post from Matthew Bass</a> explaining the solution to my problem:</p>
<pre class="code">Rake::TaskManager.class_eval do
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

def remove_task(task_name)
  Rake.application.remove_task(task_name)
end

# Override existing test task to prevent integrations
# from being run unless specifically asked for
remove_task 'db:schema:dump'

# Now define db:schema:dump again, the way we did above</pre>
<p>And that was it. It&#8217;s relatively straight-forward, but has a tendency to do strange things when rails gets updated.  So you could abstract it into <a href="http://www.taknado.com/2007/7/30/overriding-rake-tasks" title="Plugin to override or monkeypatch rake tasks">a plugin</a>, with tests, but don&#8217;t forget to test it whenever you <code>gem update rails</code>.</p>
<h3>Alternative solution</h3>
<p>While I was googling I also ran into <a href="http://playtype.net/past/2008/3/27/multiple_databases_in_rails_without/" title="alias_task_chain source">a very interesting post on <code>alias_task_chain</code></a>, a method that patches Rake tasks to work like more typical methods with <code>alias_method_chain</code>.  If you were clever and wanted to spend the time, you could get a solution to the problem using this method.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2008/05/05/howto-monkeypatch-rake-overriding-a-rake-task/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Call URLs on your app from the Rails console</title>
		<link>http://www.foliosus.com/2008/02/06/call-urls-on-your-app-from-the-rails-console/</link>
		<comments>http://www.foliosus.com/2008/02/06/call-urls-on-your-app-from-the-rails-console/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 19:46:37 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2008/02/06/call-urls-on-your-app-from-the-rails-console/</guid>
		<description><![CDATA[Here&#8217;s a neat trick I just learned from Obie Fernandez (The Rails Way, p. 30: you can see what your Rails app&#8217;s HTML output is from the console. To make this work you have to fool the app into thinking that there&#8217;s a request coming in by setting some environmental variables, and then call the [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a neat trick I just learned from Obie Fernandez (<a href="http://www.amazon.com/exec/obidos/tg/detail/-/0321445619/foliosuscom-20" title="Buy the book from Amazon">The Rails Way</a>, p. 30: you can see what your Rails app&#8217;s HTML output is from the console. To make this work you have to fool the app into thinking that there&#8217;s a request coming in by setting some environmental variables, and then call the dispatcher.</p>
<p>But wouldn&#8217;t it be nice to have a single method call, that uses <code>url_for</code> syntax?</p>
<p><span id="more-92"></span></p>
<pre class="code">class Object
  def request(options = {})
    method = options.delete(:method) || :get
    options.reverse_merge!(:only_path => true)
    ENV['REQUEST_URI'] = app.url_for(options)
    ENV['REQUEST_METHOD'] = method.to_s
    Dispatcher.dispatch
  end
end</pre>
<p>First we pull the method (<code>:get</code>, <code>:post</code> etc.) out, if it exists.  By default we want it to be <code>:get</code>.  Then we call <code>url_for</code> and have it only return the path, without any leading domain info.  Next we populate the environmental variables and call the dispatcher.  The return output will be the HTML your app renders.</p>
<p>To make the trick universally accessible on your development box, put the above code in <code>~/.irbrc</code>:</p>
<p>Then, fire up the console to your favorite rails app, and call:</p>
<pre class="code">>> request(:controller => 'my_controller', :action => 'the_action')</pre>
<p>You should see the HTML output scroll by.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2008/02/06/call-urls-on-your-app-from-the-rails-console/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Connecting Ruby on Rails to Oracle on an Intel Mac in Leopard (Mac OSX 10.5)</title>
		<link>http://www.foliosus.com/2007/11/19/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-mac-osx-105/</link>
		<comments>http://www.foliosus.com/2007/11/19/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-mac-osx-105/#comments</comments>
		<pubDate>Mon, 19 Nov 2007 16:58:15 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2007/11/19/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-mac-osx-105/</guid>
		<description><![CDATA[NOTE: This tutorial has been superseded by a newer version that takes advantage of the newly-released Intel Mac version of the Oracle InstantClient. The new version is much, much simpler, and causes far fewer headaches.
Updated (12/11/07): The ruby-oci8 library just went to full 1.0.0 release.  I&#8217;ve updated that section to reflect the new file [...]]]></description>
			<content:encoded><![CDATA[<p><strong>NOTE:</strong> This tutorial has been superseded by <a href="/2008/05/05/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-take-2/" title="Read this tutorial!  The one you're looking at isn't any good any more.">a newer version</a> that takes advantage of the newly-released Intel Mac version of the Oracle InstantClient. The new version is much, much simpler, and causes far fewer headaches.</p>
<p><strong>Updated (12/11/07):</strong> The <code>ruby-oci8</code> library just went to full 1.0.0 release.  I&#8217;ve updated that section to reflect the new file names.</p>
<p><strong>Updated (5/5/08):</strong> The oracle adapter installation has been on-again-off-again with successive Rails releases, but there&#8217;s an easy fix for it.  I&#8217;ve updated the relevant section.</p>
<p>At my new job, I&#8217;m using Ruby on Rails to connect to multiple databases — multiple Oracle (10g) instances, as well as MySQL and FileMaker.  There&#8217;s a lot of challenges to doing this, so I&#8217;m going to post some of the less obvious solutions as they come up.</p>
<p>The first challenge I had was to get RoR to talk to Oracle.  There isn&#8217;t a lot of information about this online, because the people who tend to use Oracle are not the people who tend to use open source software like Rails.</p>
<h2>Upgrade Rails to version 2.0</h2>
<p>To start out, I wanted to use the most recent release candidate of Rails: version 1.99.  I figured that I might as well upgrade before writing my first application, so that the codebase is all Rails 2.0 and up.  Leopard comes with both Ruby and Rails, and upgrading is actually very easy:<span id="more-80"></span></p>
<pre class="code">sudo gem install rails --source http://gems.rubyonrails.org</pre>
<p>Then enter “y” at each prompt, to install all of the dependencies.  That’s it!  Check yourself with</p>
<pre class="code">rails –v</pre>
<p>You should see <code>Rails 1.99.0</code> or <code>Rails 2.0</code>.</p>
<h2>Getting Rails to talk to Oracle</h2>
<p>Now,</p>
<pre class="code">sudo gem install activerecord-oracle-adapter --source http://gems.rubyonrails.org</pre>
<p>This installs the oracle adapter.  It doesn&#8217;t, however, install the Ruby oci8 driver.  We&#8217;ll do that now.</p>
<p>Make sure you’ve got the <a title="Download the Oracle Instant Client SDK" href="http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/macsoft.html">Oracle Instant Client SDK</a> installed in your Oracle Instant Client directory (/Library/Oracle/instantclient/10.1.0.3)</p>
<p>There&#8217;s a problem on new Intel Macs with this library.  Oracle hasn&#8217;t seen fit to release an Intel version of the library in the past year and a half, and that&#8217;s going to cause problems since the Ruby binary is going to run as Intel-native, but the Instant Client will run under Rosetta.  To solve this, we have to make a PPC version of the Ruby binary.</p>
<h3>Make PPC and fat versions of Ruby</h3>
<p>This is easier than it sounds.  We don&#8217;t have to recompile, since the Ruby binary in <code>/user/bin</code> is fat.  You can check this:</p>
<pre class="code">file `which ruby`</pre>
<p>This should show you a PPC and a i386 version:</p>
<pre class="code">/usr/bin/ruby_fat: Mach-O universal binary with 2 architectures
/usr/bin/ruby_fat (for architecture ppc7400):	Mach-O executable ppc
/usr/bin/ruby_fat (for architecture i386):	Mach-O executable i386</pre>
<p>All we have to do is extract the PPC version as a standalone binary, and trick the system into using that only.  It will make our Ruby slower, but it will get Ruby to talk to Oracle, so I&#8217;m willing to take the performance hit.  It&#8217;s so fast on the Intel Macs anyway, unless your Rails apps are doing massive amounts of processing, you probably won&#8217;t notice.</p>
<p>We&#8217;ll use <code>ditto</code> to extract the PPC version:</p>
<pre class="code">sudo ditto -arch ppc7400 /usr/bin/ruby /usr/bin/ruby_ppc
sudo mv /usr/bin/ruby /usr/bin/ruby_fat</pre>
<p>Now we&#8217;ve got two versions of the Ruby binary — the original fat version, and a PPC only version.</p>
<p>There&#8217;s a catch here, though: we actually have <em>two</em> copies of the <code>ruby</code> binary on our system.  The second binary is a part of the Ruby Framework, and that&#8217;s the binary that&#8217;s used by <code>irb</code>, <code>rake</code> and other very useful Rails helpers, so let&#8217;s fix this one too:</p>
<pre class="code">sudo ditto -arch ppc7400 /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby_ppc
sudo mv /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby_fat</pre>
<p>Now we&#8217;ll need a facility for switching between the fat and PPC only binaries.  Create <code>/usr/bin/ppc_ruby.sh</code>:</p>
<pre class="code">#!/bin/bash
ln -fs /usr/bin/ruby_ppc /usr/bin/ruby
ln -fs /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby_ppc /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby</pre>
<p>Create <code>/usr/bin/fat_ruby.sh</code>:</p>
<pre class="code">#!/bin/bash
ln -fs /usr/bin/ruby_fat /usr/bin/ruby
ln -fs /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby_fat /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby</pre>
<p>Now, make them both executable:</p>
<pre class="code">sudo chmod 0711 /usr/bin/ppc_ruby.sh
sudo chmod 0711 /usr/bin/fat_ruby.sh</pre>
<p>Run <code>ruby_ppc.sh</code> to switch to using the PPC version:</p>
<pre class="code">sudo /usr/bin/ppc_ruby.sh</pre>
<p>Verify this worked:</p>
<pre class="code">file `which ruby`</pre>
<p>This should return <code>/usr/bin/ruby: Mach-O executable PPC</code>.</p>
<p>We&#8217;re getting closer.  Now we need the ruby-oci8 library.</p>
<h3>Compile the ruby-oci8 library</h3>
<p>The most recent stable version of the oci8 library is <a title="Ruby oci8 library" href="http://rubyforge.org/projects/ruby-oci8/">1.0.0</a>.  Download it and unpack the file in the finder: it should unzip into <code>~/Downloads/ruby-oci8-1.0.0</code>.</p>
<p>Before we can compile this library, we have to fool the system into making it PPC only, or it&#8217;s not going to work.  With your favorite text editor, edit <code>/usr/lib/ruby/1.8/universal-darwin9.0/rbconfig.rb</code>.  Comment out line 17 (<code>'-arch ppc -arch i386'</code> and replace it with <code>'-arch ppc'</code>.  Save your changes.  Leave the file open in your text editor, because we&#8217;ll come back to it.</p>
<p>Now we can finish configuring the environment before we compile the library.</p>
<pre class="code">cd ~/Downloads/ruby-oci8-1.0.0
export DYLD_LIBRARY_PATH=/Library/Oracle/instantclient/10.1.0.3
export SQLPATH=/Library/Oracle/instantclient/10.1.0.3
ruby setup.rb config
make
sudo make install</pre>
<p>Now you can go back to your text editor and restore line 17, save your changes and exit.</p>
<h2>Test connectivity</h2>
<p>At this point, we&#8217;re done.  We&#8217;ve fooled our system into running a PPC version of Ruby under Rosetta, and we&#8217;ve installed the ruby-oci8 library.  Now it&#8217;s a question of making sure that it works:</p>
<pre class="code">ruby /usr/bin/irb</pre>
<p>In the IRb console, type:</p>
<pre class="code">require 'oci8'</pre>
<p>If the console returns <code>true</code>, you’re in business.</p>
<h2>Configure your database.yml</h2>
<p>The last step is to make your application use the Oracle connection.  In your database.yml, use the following to make it work:</p>
<pre class="code">development:
adapter: oracle
database: your_instance_name
username: your_user_name
password: your_password</pre>
<p>The database name comes straight out of your <code>/Library/Oracle/instantclient/10.1.0.3/network/admin/tnsnames.ora</code> file.  You don&#8217;t need to specify any other connection information in database.yml, since the tnsnames.ora file has everything you need.</p>
<p>Your application is now talking to Oracle!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2007/11/19/connecting-ruby-on-rails-to-oracle-on-an-intel-mac-in-leopard-mac-osx-105/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HOWTO: Upgrade your Ruby on Rails install to version 2.0 on Leopard (Mac OSX 10.5)</title>
		<link>http://www.foliosus.com/2007/11/13/howto-upgrade-your-ruby-on-rails-install-to-version-20-on-leopard-mac-osx-105/</link>
		<comments>http://www.foliosus.com/2007/11/13/howto-upgrade-your-ruby-on-rails-install-to-version-20-on-leopard-mac-osx-105/#comments</comments>
		<pubDate>Tue, 13 Nov 2007 16:37:35 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Operating systems]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2007/11/13/howto-upgrade-your-ruby-on-rails-install-to-version-20-on-leopard-mac-osx-105/</guid>
		<description><![CDATA[This one&#8217;s real easy.  Leopard ships with a default Rails installation (/usr/bin/rails), but overriding it is quite simple, since it&#8217;s just a gem.
sudo gem install rails --source http://gems.rubyonrails.org
Then, enter &#8220;y&#8221; at each prompt, to install all of the dependencies.  That’s it!  Check yourself with:
rails -v
Right now it will show Rails 1.99.0 which [...]]]></description>
			<content:encoded><![CDATA[<p>This one&#8217;s <em>real</em> easy.  Leopard ships with a default Rails installation (<code>/usr/bin/rails</code>), but overriding it is quite simple, since it&#8217;s just a <code>gem</code>.</p>
<pre class="code">sudo gem install rails --source http://gems.rubyonrails.org</pre>
<p>Then, enter &#8220;y&#8221; at each prompt, to install all of the dependencies.  That’s it!  Check yourself with:</p>
<pre class="code">rails -v</pre>
<p>Right now it will show <code>Rails 1.99.0</code> which is the current release candidate.  When rails goes fully 2.0, the same instructions should work to get the full release installed.</p>
<p>And don&#8217;t forget, you can always <code>rake rails:freeze</code> to lock a Rails app to a particular version of Rails by copying all of the Rails libraries into the <code>/vendor</code> directory.</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2007/11/13/howto-upgrade-your-ruby-on-rails-install-to-version-20-on-leopard-mac-osx-105/feed/</wfw:commentRss>
		</item>
		<item>
		<title>An &#8220;else&#8221; condition for link_to_unless_current</title>
		<link>http://www.foliosus.com/2007/04/18/else_for_link_to_unless_current/</link>
		<comments>http://www.foliosus.com/2007/04/18/else_for_link_to_unless_current/#comments</comments>
		<pubDate>Thu, 19 Apr 2007 04:17:21 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2007/04/18/else_for_link_to_unless_current/</guid>
		<description><![CDATA[Every time I get frustrated with an aspect of Rails, it turns out that it&#8217;s just my idiocy and not actually something to do with Rails.
Most recently, I wanted to code this algorithm:
If on the current page
  show &#60;a href="blah1"&#62;link 1&#60;/a&#62;
else
  show &#60;a href="blah2&#62;link 2&#60;/a&#62;

Rails has, of course, the nifty link_to_unless_current, but all [...]]]></description>
			<content:encoded><![CDATA[<p>Every time I get frustrated with an aspect of Rails, it turns out that it&#8217;s just my idiocy and not actually something to do with Rails.</p>
<p>Most recently, I wanted to code this algorithm:</p>
<pre class="code">If on the current page
  show &lt;a href="blah1"&gt;link 1&lt;/a&gt;
else
  show &lt;a href="blah2&gt;link 2&lt;/a&gt;</pre>
<p><span id="more-69"></span></p>
<p>Rails has, of course, the nifty <span class="code">link_to_unless_current</span>, but all that does is show the text of the link:</p>
<pre class="code">If on the current page
  show link
else
  show &lt;a href="blah"&gt;link&lt;/a&gt;</pre>
<p>That&#8217;s not quite what I&#8217;m looking for.  But when I was looking up link_to_unless_current in the <a href="http://api.rubyonrails.org/" title="The full Rails API">docs</a>, I realized that there IS an else condition on <span class="code">link_to_unless_current</span>.  The function takes a block as its last parameter, and that&#8217;s what gives you the &#8220;else.&#8221;</p>
<p>This code, in a view:</p>
<pre class="code">&lt;%= link_to_unless_current('Link text', my_url) { 'Alternate text' } %&gt;</pre>
<p>produces this algorithmic result:</p>
<pre class="code">If on the current page
  show Alternate text
else
  show &lt;a href="my_url"&gt;Link text&lt;/a&gt;</pre>
<p>Mission accomplished.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2007/04/18/else_for_link_to_unless_current/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ruby on Rails has the same appeal as the MacOS</title>
		<link>http://www.foliosus.com/2006/08/05/ruby-on-rails-has-the-same-appeal-as-the-macos/</link>
		<comments>http://www.foliosus.com/2006/08/05/ruby-on-rails-has-the-same-appeal-as-the-macos/#comments</comments>
		<pubDate>Sat, 05 Aug 2006 19:21:10 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[Operating systems]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/08/05/ruby-on-rails-has-the-same-appeal-as-the-macos/</guid>
		<description><![CDATA[Why do people flip out over RoR?  Primarily, because it&#8217;s fast.  It&#8217;s so fast to develop new applications in RoR.  But why?  What separates RoR from any of the other frameworks out there?  The approach that defines RoR is &#8220;convention over configuration,&#8221; and that&#8217;s where much of the speed comes [...]]]></description>
			<content:encoded><![CDATA[<p>Why do people flip out over <a title="Ruby on Rails, a web application framework" href="http://www.rubyonrails/">RoR</a>?  Primarily, because it&#8217;s fast.  It&#8217;s so fast to develop new applications in RoR.  But why?  What separates RoR from any of the other frameworks out there?  The approach that defines RoR is &#8220;convention over configuration,&#8221; and that&#8217;s where much of the speed comes from.   I had an epiphany this morning: &#8220;convention over configuration&#8221; sounds familliar.  That&#8217;s why I use a Mac.<span id="more-50"></span></p>
<p>My current job is really the first time I&#8217;ve had to use Windows regularly since Windows for Workgroups 3.11.  That&#8217;s way back in 1995 when Windows 95 was still vaporware, much like Vista is now.  Isn&#8217;t it already 3 years overdue?  Anyway, that&#8217;s not relevant to this discussion.</p>
<p>I&#8217;ve had many discussions with people over the years about the old Mac vs. Windows debate.  I&#8217;m no rabid Mac advocate: it&#8217;s not the best solution for all people at all times.  Hardcore Windows users frequently complain that on the Mac there is no Registry, that you can&#8217;t really configure hardware devices etc.  I would argue that on the Mac you don&#8217;t have to.  It&#8217;s convention over configuration.</p>
<p>When I first started using a Mac, I had many of the same misgivings.  Where were the menus with the bazillion options to choose from?  Why couldn&#8217;t I regulate every little detail of the interface?  As I used my Mac more, I realized that I didn&#8217;t have to.  The configuration options I wanted were absent, but the need for them was absent as well.  And I say the MacOS is better off for it, because it lowers the barrier to entry.</p>
<p>I frequently think about interface design in terms of my mom.  I know, a lot of people do this, but it works.  My mom has fought with Windows for years: it doesn&#8217;t do things the way she wants.  What she doesn&#8217;t realize is that she probably can make it work the way she wants it to, if only she knew how.  And therein lies the problem.  It&#8217;s too complicated to get Windows configured just so, and so most users end up just living with it.  Why should a $300 piece of software just be &#8220;lived with?&#8221;</p>
<p>The MacOS takes a different approach.  It comes with a working configuration that is easier to use than what you get with Windows, and with fewer options.  This means that the application and system interface isn&#8217;t cluttered with 1001 widgets all of which let you configure system, and so all you see are the features you want access to.  This seems to be the goal of the UI revisions in &#8220;Office 12,&#8221; but they still don&#8217;t seem to have figured it out.  Too many options mean that most of them just don&#8217;t get used.</p>
<p>If the system has good <em>conventions</em>, or default options, then you don&#8217;t have to spend your time fighting with it, and it generally does 95% of the tasks that 95% of users need done without any hassle.  This is true of the Mac OS, and it&#8217;s true of RoR.  The main difference is that the RoR folks have made their goal explicit.</p>
<p>Accomplishing 95% of what I want to do easily: that&#8217;s design elegance.</p>
<p>&lt;/epiphany&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/08/05/ruby-on-rails-has-the-same-appeal-as-the-macos/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HOWTO: Lighttpd with SSL, Rails, PHP and MySQL on OSX 10.4 (Tiger)</title>
		<link>http://www.foliosus.com/2006/04/04/howto-lighttpd-with-ssl-rails-php-and-mysql-on-osx-104-tiger/</link>
		<comments>http://www.foliosus.com/2006/04/04/howto-lighttpd-with-ssl-rails-php-and-mysql-on-osx-104-tiger/#comments</comments>
		<pubDate>Tue, 04 Apr 2006 17:48:44 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Lighttpd]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/04/04/howto-lighttpd-with-ssl-rails-php-and-mysql-on-osx-104-tiger/</guid>
		<description><![CDATA[I&#8217;ve run Apache on my Mac for as long as I&#8217;ve had OSX, using either the built-in version or the ServerLogistics package, which they don&#8217;t make anymore.  It always worked great, and when I started learning PHP, it was easy to install and make work.  Getting SSL to work was a little bit [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve run Apache on my Mac for as long as I&#8217;ve had OSX, using either the built-in version or the <a href="http://www.serverlogistics.com/" title="Good installer package for MySQL">ServerLogistics</a> package, which they don&#8217;t make anymore.  It always worked great, and when I started learning PHP, it was <a href="http://www.entropy.ch/software/macosx/php/" title="PHP installer package">easy to install</a> and make work.  Getting SSL to work was a little bit more of a challenge, but once I found <a href="http://forums.serverlogistics.com/viewtopic.php?t=494" title="SSL for Apache 2.0">the right instructions</a> it was a breeze.</p>
<p>But now I need to serve Rails as well.  Getting Apache to do RoR with fcgi can be a hassle, and it&#8217;s apparently slow as well, so I decided to switch to <a href="www.lighttpd.net" title="Lighty home">lighttpd</a>, or lighty as it&#8217;s called.</p>
<p>For development purposes, using the standard <span class="code">script/server</span> is a no-brainer; however I want a &#8220;production&#8221; environment as well.  One that can serve Rails, and legacy PHP, and do SSL for authentication, while talking to MySQL.  I discovered that lighty can do all of these things, but how?<span id="more-34"></span></p>
<p>I looked around, and once you get to the deployment phase of RoR, there isn&#8217;t a lot of good information on the web, especially for smaller set-ups like mine; essentially, I&#8217;m almost the only person who hits my web server, as it houses some personal productivity stuff just for me that most other people don&#8217;t find interesting.  That and my photo collection for friends to browse.</p>
<p>So I looked and looked, and found a lot of disjointed bits and bobs, but I didn&#8217;t find a good how-to for non-unix geeks.  But, given the ease of use of lighty, I&#8217;ve put one together.  Enjoy!</p>
<h3>Requirements</h3>
<ol>
<li>Tiger (OSX 10.4)</li>
<li>XCode 2.0 or newer and developer&#8217;s tools</li>
<li>Patience and a nice snack while waiting for compiling to happen</li>
</ol>
<h3 id="rubyetc">Building Ruby, Gems, RoR, FastCGI, PCRE</h3>
<p>Go to <a href="http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger">Dan Benjamin&#8217;s excellent instructions</a> to do all of these things, and follow them well.  However, stop when you get to the lighttpd instructions, because we&#8217;re going to make a change.  Do this instead of what he says:</p>
<pre class="code" name="lighttpd">curl -O http://lighttpd.net/download/lighttpd-1.4.11.tar.gz
tar xzvf lighttpd-1.4.11.tar.gz
cd lighttpd-1.4.11
./configure --prefix=/usr/local --with-pcre=/usr/local --with-openssl
make
sudo make install
cd ..</pre>
<p>The only difference is the addition of <span class="code">&#8211;with-openssl</span> to the configuration, which will compile lighttpd with SSL (v2 and v3) support.</p>
<h3 id="mysql">Building MySQL</h3>
<p>You can choose to build MySQL according to <a href="http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger">the HiveLogic instructions</a>, or you can use the <a href="http://dev.mysql.com/downloads/mysql/5.0.html#Mac_OS_X" title="MySQL 5.0 download page">MySQL 5.0 packages</a> from the dolphin&#8217;s mouth, so to speak, and avoid the compile time.  This works for <a href="http://dev.mysql.com/downloads/mysql/4.1.html#Mac_OS_X" title="MySQL 4.1 download page">version 4.1</a> as well.  I&#8217;ve tried both versions with the setup described here, and both work.</p>
<p>Don&#8217;t forget to install the MySQL native bindings (again, from <a href="http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger">the HiveLogic instructions</a>) as well.</p>
<h3>But, I&#8217;ve already got this stuff working!</h3>
<p>Chances are, you&#8217;ve already got a full setup that works, because you saw <a href="http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger">the HiveLogic instructions</a> long before I ever wrote this page.  If that&#8217;s the case, then all you need to do is follow <a href="#lighttpd">my lighttpd compile instructions</a>, which will over-write the pre-existing lighttpd version, with no ill effects.</p>
<h3 id="php">Building PHP</h3>
<p>First, <a href="http://www.php.net/downloads.php" title="PHP download page">download the PHP 5.1.2 full source code</a>, and unpack the tarball by double-clicking it in the finder.  I would recommend moving the unpacked &#8220;php-5.1.2&#8243; folder to the same folder where you downloaded all of the source code from <a href="http://hivelogic.com/articles/2005/12/01/ruby_rails_lighttpd_mysql_tiger">the hivelogic instructions</a>.</p>
<p>Second, open a terminal, and execute the following commands:</p>
<pre class="code">./configure --enable-fastcgi --enable-discard-path --enable-force-redirect --with-zlib --with-xml --with-mysql=/usr/local/mysql --prefix=/usr/local/php5-fcgi --disable-cli --enable-memory-limit --with-layout=GNU --with-regex=php
make
sudo make install</pre>
<p>When this is done, you&#8217;ll have a working cgi-fcgi version of PHP.  We&#8217;ll hook this up to lighttpd in a minute, when we get to the lighty configuration files.</p>
<h3 id="ssl">SSL</h3>
<p>Before we start configuring lighty, we&#8217;ve got to get an SSL certificate.  If you&#8217;re creating your own, you can follow the instructions from the lighty web site:</p>
<pre class="code">openssl req -new -x509 -keyout host.pem -out host.pem -days 365 -nodes</pre>
<p>If you already have a certificate that&#8217;s a .crt and a .key file, you have to make them snuggle up into a single .pem file:</p>
<pre class="code">cat host.key host.crt > host.pem</pre>
<p>Both of these methods result in a single .pem file, usually named &#8220;host.pem&#8221; where &#8220;host&#8221; is the name of the server you&#8217;re using the certificate for.  This file can be stored anywhere you want on your system, since the lighty configuration takes an explicit path to it.</p>
<h3 id="lighttpdconfig">Configuring lighttpd</h3>
<p>Now the more difficult part: we get to configure lighty.  I&#8217;ll present the config files one chunk at a time, explaining what the various commands do.  I&#8217;ve chosen to store mine in <span class="code">/etc/lighttpd/</span> to mimic how Apache stores its files (<span class="code">/etc/httpd/</span>).  Any path will do, just change the references to that directory in the coming intsructions.</p>
<p>First, we&#8217;ll set up 2 top-level files, which are both quite simple.  They set up two nearly identical configurations for the lighty daemon, that run side-by-side.  The first scans port 80, and serves http requests.  Let&#8217;s call this file <span class="code">lighttpd.conf</span>.</p>
<pre class="code">include "lighttpd_shared.conf"

server.port = 80

server.errorlog    = "/etc/lighttpd/lighttpd.error.log"
accesslog.filename = "/etc/lighttpd/lighttpd.access.log"</pre>
<p>The first line causes lighty to parse the main configuration file, which we&#8217;ll go through below.  The next line binds lighty to port 80, the default for http, and then we assign error log files.</p>
<p>We do something very similar for the other top-level file, the one that configures the SSL daemon.  I&#8217;ve called mine <span class="code">lighttpd_ssl.conf</span>.</p>
<pre class="code">include "lighttpd_shared.conf"

server.port = 443

server.errorlog    = "/etc/lighttpd/lighttpd_ssl.error.log"
accesslog.filename = "/etc/lighttpd/lighttpd_ssl.access.log"

ssl.engine         = "enable"
ssl.pemfile        = "/etc/lighttpd/host.pem"</pre>
<p>In this case, we&#8217;ve bound the daemon to port 443, the default for secure connections.  We&#8217;ve specified log files, and then enabled the SSL engine and specified the path to the .pem file.</p>
<p>By the way, the log files must exist before you run the daemon, and have the right permissions.  To do this, simply touch the files, assign them to &#8220;www&#8221; and set the permissions:</p>
<pre class="code">cd /etc/lighttpd
touch lighttpd.error.log
touch lighttpd.access.log
touch lighttpd_ssl.error.log
touch lighttpd_ssl.access.log
sudo chown www *.log
sudo chmod 0666 *log</pre>
<p>Now, on to the meat of the matter.  Both of our top-level files parse the <span class="code">lighttpd_shared.conf</span> file, so that both daemons run in parallel and do the same things.  This means that all pages in our web server can be served with a regular or a secure connection.  Here&#8217;s the meat:</p>
<pre class="code">server.modules = ( "mod_rewrite",
                   "mod_access",
                   "mod_fastcgi",
                   "mod_userdir",
                   "mod_accesslog" )

# Main folder containing web documents
server.document-root = "path/to/main/"

# Allow http://www.domain.com/~username/ style requests
userdir.basepath = "/Users/"
userdir.path = "Sites"
userdir.include-user = ("username") # only allow requests for this user (optional)

# If no file is specified, what to look for?
index-file.names = ( "index.html", "index.htm", "index.php" )

# Required event handler for OS X
server.event-handler = "freebsd-kqueue"

# Run the server under the user-name "www" for security purposes
# To bind to port 80, the server must be called by root user, but we don't want
# the server to have free run of the box, so it runs as "www"
server.username = "www"
server.groupname = "www"

# Set up the appropriate MIME type mappings
mimetype.assign             = (
  ".pdf"          =>      "application/pdf",
  ".sig"          =>      "application/pgp-signature",
  ".spl"          =>      "application/futuresplash",
  ".class"        =>      "application/octet-stream",
  ".ps"           =>      "application/postscript",
  ".torrent"      =>      "application/x-bittorrent",
  ".dvi"          =>      "application/x-dvi",
  ".gz"           =>      "application/x-gzip",
  ".pac"          =>      "application/x-ns-proxy-autoconfig",
  ".swf"          =>      "application/x-shockwave-flash",
  ".tar.gz"       =>      "application/x-tgz",
  ".tgz"          =>      "application/x-tgz",
  ".tar"          =>      "application/x-tar",
  ".zip"          =>      "application/zip",
  ".mp3"          =>      "audio/mpeg",
  ".m3u"          =>      "audio/x-mpegurl",
  ".wma"          =>      "audio/x-ms-wma",
  ".wax"          =>      "audio/x-ms-wax",
  ".ogg"          =>      "application/ogg",
  ".wav"          =>      "audio/x-wav",
  ".gif"          =>      "image/gif",
  ".jpg"          =>      "image/jpeg",
  ".jpeg"         =>      "image/jpeg",
  ".png"          =>      "image/png",
  ".xbm"          =>      "image/x-xbitmap",
  ".xpm"          =>      "image/x-xpixmap",
  ".xwd"          =>      "image/x-xwindowdump",
  ".css"          =>      "text/css",
  ".html"         =>      "text/html",
  ".htm"          =>      "text/html",
  ".js"           =>      "text/javascript",
  ".asc"          =>      "text/plain",
  ".c"            =>      "text/plain",
  ".cpp"          =>      "text/plain",
  ".log"          =>      "text/plain",
  ".conf"         =>      "text/plain",
  ".text"         =>      "text/plain",
  ".txt"          =>      "text/plain",
  ".dtd"          =>      "text/xml",
  ".xml"          =>      "text/xml",
  ".mpeg"         =>      "video/mpeg",
  ".mpg"          =>      "video/mpeg",
  ".mov"          =>      "video/quicktime",
  ".qt"           =>      "video/quicktime",
  ".avi"          =>      "video/x-msvideo",
  ".asf"          =>      "video/x-ms-asf",
  ".asx"          =>      "video/x-ms-asf",
  ".wmv"          =>      "video/x-ms-wmv",
  ".bz2"          =>      "application/x-bzip",
  ".tbz"          =>      "application/x-bzip-compressed-tar",
  ".tar.bz2"      =>      "application/x-bzip-compressed-tar"
 )

# Don't server these files statically, for security
static-file.exclude-extensions = ( ".fcgi", ".php", ".rb", "~", ".inc", ".pl", ".yml" )

# Use mod_access to deny direct access to files ending in ~ or .inc; these are usually
# code or backup files
url.access-deny             = ( "~", ".inc" )

# Disable auto-generated directory listings, for security
dir-listing.activate        = "disable"

# Disable range requests for PDF files
$HTTP["url"] =~ &#8220;\.pdf$&#8221; {
  server.range-requests = &#8220;disable&#8221;
}

# Set up a fastcgi server for PHP
fastcgi.server = ( &#8220;.php&#8221; => ((
                     &#8220;bin-path&#8221; => &#8220;/usr/local/php5-fcgi/bin/php&#8221;, # path to php binary
                     &#8220;socket&#8221; => &#8220;/tmp/php.socket&#8221;,
                 )))

# Now create virtual subdomains for each rails app we want; myrailsapp.domain.com
# Repeat the following block for each rails app, and for each one
# replace &#8220;myrailsapp&#8221; with the name of your application
# This sets up separate fcgi processes for each application

$HTTP["host"] =~ &#8220;^myrailsapp\.&#8221; {
     var.myrailsapp = &#8220;/path/to/rails/app&#8221;
     server.document-root = var. myrailsapp + &#8220;/public&#8221;
     server.error-handler-404 = &#8220;/dispatch.fcgi&#8221;
     fastcgi.server = ( &#8220;.fcgi&#8221; =>
                     ( &#8220;localhost&#8221; =>
                         ( &#8220;bin-environment&#8221; => (&#8221;RAILS_ENV&#8221; => &#8220;production&#8221;),
                           &#8220;bin-path&#8221; => var. myrailsapp + &#8220;/public/dispatch.fcgi&#8221;,
                            &#8220;socket&#8221; => &#8220;/tmp/myrailsapp.fcgi.socket&#8221;
                         )
                      )
                 )
}</pre>
<p>You can tweak the fastcgi performance by using <a href="http://www.lighttpd.net/documentation/fastcgi.html" title="Lighttpd fastcgi configuration options">the lighttpd instructions</a> for directives such as &#8220;min-procs&#8221; and &#8220;max-procs&#8221; but that&#8217;s up to you.</p>
<h3 id="launchd">Lighty at startup</h3>
<p>Wouldn&#8217;t it be nice if lighty launched at startup, and we didn&#8217;t have to worry about it?  How about if it relaunched whenever it crashed?  That would be even better.  Save the following to <span class="code">/Library/LaunchDaemons/net.lighttpd.plist</span> and watch the magic happen, thanks to <a href="http://textsnippets.com/posts/show/124" title="Original launchd instructions">froehle</a>:</p>
<pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
	&lt;key&gt;Label&lt;/key&gt;
	&lt;string&gt;net.lighttpd&lt;/string&gt;
	&lt;key&gt;OnDemand&lt;/key&gt;
	&lt;false /&gt;
	&lt;key&gt;Program&lt;/key&gt;
	&lt;string&gt;/usr/local/sbin/lighttpd&lt;/string&gt;
	&lt;key&gt;ProgramArguments&lt;/key&gt;
	&lt;array&gt;
		&lt;string&gt;/usr/local/sbin/lighttpd&lt;/string&gt;
		&lt;string&gt;-f/path/to/lighttpd.conf&lt;/string&gt;
		&lt;string&gt;-D&lt;/string&gt;
	&lt;/array&gt;
&lt;/dict&gt;
&lt;/plist&gt;</pre>
<p>Oh, wait, before the magic, there&#8217;s one more (<span class="code">/Library/LaunchDaemons/net.lighttpd_ssl.plist</span>):</p>
<pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
	&lt;key&gt;Label&lt;/key&gt;
	&lt;string&gt;net.lighttpd_ssl&lt;/string&gt;
	&lt;key&gt;OnDemand&lt;/key&gt;
	&lt;false /&gt;
	&lt;key&gt;Program&lt;/key&gt;
	&lt;string&gt;/usr/local/sbin/lighttpd&lt;/string&gt;
	&lt;key&gt;ProgramArguments&lt;/key&gt;
	&lt;array&gt;
		&lt;string&gt;/usr/local/sbin/lighttpd&lt;/string&gt;
		&lt;string&gt;-f/path/to/lighttpd_ssl.conf&lt;/string&gt;
		&lt;string&gt;-D&lt;/string&gt;
	&lt;/array&gt;
&lt;/dict&gt;
&lt;/plist&gt;</pre>
<p>Of course, if you&#8217;ve installed the lighttpd binary someplace other than <span class="code">/usr/local/sbin</span> then you should change those 2 lines in each .plist file, and you should specify the path to your .conf files properly.</p>
<h3 id="graceful">Graceful restarts</h3>
<p>Wouldn&#8217;t it be super-nice if we could issue graceful restart commands?  It&#8217;s actually very easy in Tiger (10.4) since launchd monitors apps it has started, and re-opens them if they&#8217;ve quit or crashed.  That means that all we have to do is cause a graceful shutdown, and launchd will take care of the restart for us.  Put the following in <span class="code">/usr/local/sbin/</span> in a file called &#8220;lighttpdctl&#8221; (named after apachectl) with the appropriate path to your config files:</p>
<pre class="code">#!/bin/sh
sudo killall -9 lighttpd</pre>
<p>Make it executable by doing this:</p>
<pre class="code">chmod u+x /usr/local/sbin/lighttpdctl</pre>
<p>Now, from anywhere (since <span class="code">/usr/local/sbin</span> is in our path), you can call <span class="code">lighttpdctl</span> to do a graceful restart.  Note, if you&#8217;re running a port 3000-bound <span class="code">script/server</span> development instance of lighty, it will also quit.</p>
<h3>We&#8217;re done</h3>
<p>Well, almost.  You now have to restart your machine to have launchd do its thing.  If you issue the kill command to lighttpd and the configuration is bad (for whatever reason), and lighty bails on startup, launchd will no longer monitor the process.  This means that when you&#8217;re mucking around, there&#8217;s a lot of <span class="code">sudo lighttpd -f/etc/lighttpd/lighttpd.conf -D</span> from the prompt until you&#8217;ve got it working, followed by a restart.  I&#8217;m pretty sure that there&#8217;s a better way to do the config debugging, but I&#8217;m not 1337 enough with FreeBSD and launchd-speak to do it any better.  If somebody out there knows, please post it in the comments.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/04/04/howto-lighttpd-with-ssl-rails-php-and-mysql-on-osx-104-tiger/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Lighttpd url rewrites are funny</title>
		<link>http://www.foliosus.com/2006/03/20/lighttpd-url-rewrites-are-funny/</link>
		<comments>http://www.foliosus.com/2006/03/20/lighttpd-url-rewrites-are-funny/#comments</comments>
		<pubDate>Mon, 20 Mar 2006 18:56:58 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Lighttpd]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/03/20/lighttpd-url-rewrites-are-funny/</guid>
		<description><![CDATA[Since I&#8217;ve been playing around with RoR I&#8217;ve found the
script/server
trick for development to be fantastically useful.  It&#8217;s quick to use, the server itself is fast, and it&#8217;s everything I could want.  That is, until it&#8217;s time to go in to production mode.  I&#8217;ve been running Apache, using OSX&#8217;s built-in build, but I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>Since I&#8217;ve been playing around with RoR I&#8217;ve found the</p>
<pre class="code">script/server</pre>
<p>trick for development to be fantastically useful.  It&#8217;s quick to use, the server itself is fast, and it&#8217;s everything I could want.  That is, until it&#8217;s time to go in to production mode.  I&#8217;ve been running Apache, using OSX&#8217;s built-in build, but I&#8217;m considering switching my whole setup over to lighty because of the funkiness of Apache and Ruby&#8217;s fcgi.  So I tried it.  Building lighty was really easy.  Getting lighty to then serve my static pages was also very easy.  Then I tried getting it to serve my ruby apps, and that&#8217;s where the problems hit.<span id="more-32"></span></p>
<p>It turns out that my one big config problem was this: &#8220;url.rewrite&#8221; does not work inside a $HTTP["url"] matching block.  So, for example consider this case, where I want to rewrite URL&#8217;s intended for my rails app which has 2 controllers, admin and view:</p>
<pre class="code">$HTTP["url"] =~ &#8220;^/input_path/&#8221; {
  url.rewrite-once (&#8221;/(admin|view)/(.*)&#8221; => &#8220;/some/other/path/$1/$2&#8243;)
}</pre>
<p>If the incoming URL matches &#8220;/input_path/&#8221; then lighty starts processing the code inside the braces, but the url.rewrite-once fails to act.  Instead, the server will invariably look for files inside /input_path/ and serve up a 404.</p>
<p>The proper way to do this sort of work with lighty is to have the regex do all the work:</p>
<pre class="code">url.rewrite-once ("^/input_path/(admin|view)/(.*)" => "some/other/path/$1/$2")</pre>
<p>This isn&#8217;t documented anywhere on the <a href="http://www.lighttpd.net/documentation/" title="LightTPD docs">lighty web site</a>, but there is a <a href="http://article.gmane.org/gmane.comp.web.lighttpd/2992" title="The only documentation?">message on the lighty mailing list</a> that points out the problem.</p>
<p>I have to say, other than this hitch, I&#8217;ve been very impressed with the speed and ease of configuration that lighty offers.  Once I get PHP to work with it, I&#8217;ll be a happy camper.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/03/20/lighttpd-url-rewrites-are-funny/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RoR caching and routing</title>
		<link>http://www.foliosus.com/2006/03/15/ror-caching-and-routing/</link>
		<comments>http://www.foliosus.com/2006/03/15/ror-caching-and-routing/#comments</comments>
		<pubDate>Wed, 15 Mar 2006 15:57:18 +0000</pubDate>
		<dc:creator>Brent Miller</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.foliosus.com/2006/03/15/ror-caching-and-routing/</guid>
		<description><![CDATA[I&#8217;ve been trying to learn Ruby on Rails.  So far I&#8217;ve found it to be a very elegant solution to the problem of writing web apps.  Until now I&#8217;ve used Tango or PHP, but I hope that I never have to use them again.
I recently had a rather interesting problem, however.  My [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been trying to learn Ruby on Rails.  So far I&#8217;ve found it to be a very elegant solution to the problem of writing web apps.  Until now I&#8217;ve used Tango or PHP, but I hope that I never have to use them again.</p>
<p>I recently had a rather interesting problem, however.  My first teaching project was a little app to generate a bookmarks page, and it allows me to categorize bookmarks.  Relatively straightforward, right?  Well, I got the code to handle logging in, the categories, subcategories and bookmarks done just fine with no hitches, but then I wanted to test out caching.<span id="more-31"></span></p>
<p>In development.rb I set caching to true, and then enable page caching on my &#8220;view&#8221; controller &emdash; the one that is not behind the login and simply outputs the bookmarks list.  I reload the page, and presto, the index.html page magically appears in my app&#8217;s public folder.  &#8220;Sweet,&#8221; I think.  I then edit one of the pieces of bookmark data, and my sweeper class kicks in, logs that it is expiring the page, and then expires the page.</p>
<pre class="code">
  def expire_view(model)
    model.logger.info("Expiring the cached index")
    expire_page(:controller => "view", :action => "index")
  end
</pre>
<p>Except that the page doesn&#8217;t actually expire.  What the f*@#!?!</p>
<p>After several days of poking around, trying action caching instead, and a few posts to various forums, I figured out what the problem was.  I had reconfigured my routes.rb to essentially point all bogus URL&#8217;s to the view::index action, which was the page being cached.  After I changed routes.rb back, the page started expiring.  I&#8217;m guessing that :caches_page and expire_page() only work when there are single URL&#8217;s pointing to the page being cached.  Has anybody else had a similar experience?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.foliosus.com/2006/03/15/ror-caching-and-routing/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
