<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>tail -f development.log &#187; rails</title>
	<atom:link href="http://craigjolicoeur.com/blog/category/rails/feed" rel="self" type="application/rss+xml" />
	<link>http://craigjolicoeur.com/blog</link>
	<description>code with a purpose</description>
	<lastBuildDate>Sun, 16 May 2010 13:46:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How to integrate punBB into an existing Ruby on Rails application</title>
		<link>http://craigjolicoeur.com/blog/how-to-integrate-punbb-into-an-existing-ruby-on-rails-application</link>
		<comments>http://craigjolicoeur.com/blog/how-to-integrate-punbb-into-an-existing-ruby-on-rails-application#comments</comments>
		<pubDate>Sat, 30 May 2009 15:32:12 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[forums]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[punBB]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=133</guid>
		<description><![CDATA[A quick tutorial on how to integrate the punBB forum system into an existing Rails application with a single sign-on for both systems.]]></description>
			<content:encoded><![CDATA[<p>I released launched a rails side project, <a href="http://xboxmma.com">XBoxMMA.com</a>, and one of the most requested features by the initial users was the addition of forums to the site.</p>
<p>Thinking it over, I clearly had two options: 1) code my own custom forum system for the site, or 2) use an existing forum system.</p>
<p>While I don&#8217;t mind coding forums for the site, I really didn&#8217;t want to set aside the time needed for coding when I could have been working on plenty of other projects.  So, I set out researching existing forum software that I could utilize.</p>
<p>In searching for a third-party forum system, I really only had one major requirement &#8211; users needed to be able to login to the main website and be authenticated at the same time on the forums.  I didn&#8217;t want my users to have to maintain separate accounts and separate logins for the forums and the main website.  If I did, there would be no need for this tutorial as implementing standalone forums is a basic task.</p>
<p><span id="more-133"></span>First off, I researched existing forum systems that were already rails based, hoping there was something I could quickly integrate into my app.  I checked out all the regular suspects like Beast, <a href="http://github.com/courtenay/altered_beast/tree/master">Altered Beast</a>, <a href="http://code.google.com/p/savage-beast-2/">Savage Beast 2</a>, and the new <a href="http://github.com/radar/rboard/tree/master">rBoard</a>.</p>
<p>Of the existing rails forums, rBoard showed the most promise but none of them really work well for integrating into an existing, established rails app.  All of the rails options are really intended for standalone use as a forum only.</p>
<p>Next I proceeded to research non-Rails based forums like <a href="http://bbpress.org/">bbPress</a>, <a href="http://www.vbulletin.com/">vBulletin</a>, <a href="http://www.phpbb.com/">phpBB</a> and a handful of others.</p>
<p>I ended up settling on the <a href="http://punbb.informer.com/">punBB</a> forum software, written in PHP.  I chose punBB for a few reasons: 1) it was a lightweight forum system, 2) it seemed to get good reviews online, and 3) I was able to find some existing information online on integrating punBB with Rails.</p>
<p>Terrell Russell wrote two blog posts (<a href="http://weblog.terrellrussell.com/2008/01/running-php-within-rails/">post one</a>, <a href="http://weblog.terrellrussell.com/2008/01/generating-a-rails-and-punbb-and-dokuwiki-shared-cookie/">post two</a>) regarding running PHP from within a Rails environment and how to get punBB (and DokuWiki) running within a Rails app using single sign-on.  I used Terrell&#8217;s posts as a starting point for my project as some of his information is now outdated for both Rails 2.3x and punBB 1.3x.</p>
<p>Now, on to the tutorial.</p>
<p>My next decision was to choose how exactly to integrate the PHP code into my Rails app.  I could put the forum&#8217;s PHP code into my application&#8217;s
<pre class="brush: plain; light: true;">RAILS_ROOT/public/forums/</pre>
<p> directory, or I could install the forums somewhere else on my servers file system.</p>
<p>Since the forums really are their own separate application, and the code is independent of my Rails code, I decided to install punBB on its own and leave it out of my source repository.  This will allow me to maintain/upgrade/modify the forum software without touching my Rails repository.</p>
<blockquote><p>As a side note, your server must be able to run PHP.  My app server is a <a href="http://www.debian.org/">Debian Lenny</a> system and I installed PHP via the normal
<pre class="brush: bash; light: true;">$ sudo aptitude install</pre>
<p> routine.  (Installing PHP on your server is beyond the scope of this tutorial.)</p></blockquote>
<p>I went ahead and setup the punBB files into
<pre class="brush: plain; light: true;">/var/www/punbb</pre>
<p> on my server.  I want users to be able to access the forums by visiting <a href='http://xboxmma.com/forums/'>http://xboxmma.com/forums</a>, so there were a few additional steps I needed to take.</p>
<p>First, when I deploy my app via <a href="http://www.capify.org/">capistrano</a>, I setup a symlink in the public directory to point to my forum installation.  I also copy the forum config file into my Rails app config directory (I&#8217;ll explain why later).  Add the following code to your capistrano deploy file.</p>
<pre class="brush: ruby;">
# RAILS_ROOT/config/deploy.rb
desc &amp;quot;Setup settings for punBB forums&amp;quot;
task :after_symlink, :roles =&amp;gt; [:app] do
  run &amp;quot;ln -nfs /var/www/punbb #{release_path}/public/forums&amp;quot;
  run &amp;quot;cp /var/www/punbb/config.php #{release_path}/config&amp;quot;
end
</pre>
<p>My app server uses <a href="http://wiki.nginx.org/Main">Nginx</a> as the web front end, so I also needed to update my nginx configuration to properly route requests for the new forums.</p>
<p>My existing nginx configuration file looked like this</p>
<pre class="brush: plain;">
server {
        listen  80;
        server_name xboxmma.com;
        root /home/deploy/xboxmma.com/current/public;
        passenger_enabled on;
        access_log off;
        client_max_body_size 20M;

        location ~* \.(ico|css|js|gif|jp?g|png)(\?[0-9]+)?$ {
                expires max;
                break;
        }

        if (-f $request_filename) {
                break;
        if (-f $document_root/system/maintenance.html) {
                rewrite ^(.*)$ /system/maintenance.html break;
        }

        error_page 500 502 503 504 /500.html;
        location = /500.html {
                root /home/deploy/xboxmma.com/current/public;
        }
}
</pre>
<p>I updated it with the following sections</p>
<pre class="brush: plain;">
        location /forums {
                root /var/www/punbb;
                index index.php;

                if (-f $request_filename) {
                        expires 30d;
                        break;
                }

                if (!-e $request_filename) {
                        rewrite ^(.+)$ /forums/index.php?q=$1 last;
                }
        }

        location ~ \.php$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /opt/nginx/conf/fastcgi_params;
        }

        location ~ /\.ht {
                deny all;
        }
</pre>
<p>The
<pre class="brush: plain; light: true;">location /forums {}</pre>
<p> block will process all requests that are made to the /forums path on my site.  I set the document root to
<pre class="brush: plain; light: true;">/var/www/punbb</pre>
<p> where I installed the punBB software and set the index page to index.php.</p>
<p>The
<pre class="brush: plain; light: true;">location ~ \.php$ {}</pre>
<p> block catches any request for a php page and passes the request along to the php5-cgi processor to handle the request.</p>
<p>The end result config file looks like this:</p>
<pre class="brush: plain;">
server {
        listen  80;
        server_name xboxmma.com;
        root /home/deploy/xboxmma.com/current/public;
        passenger_enabled on;
        access_log off;
        client_max_body_size 20M;

        location ~* \.(ico|css|js|gif|jp?g|png)(\?[0-9]+)?$ {
                expires max;
                break;
        }

        location /forums {
                root /var/www/punbb;
                index index.php;

                if (-f $request_filename) {
                        expires 30d;
                        break;
                }

                if (!-e $request_filename) {
                        rewrite ^(.+)$ /forums/index.php?q=$1 last;
                }
        }

        location ~ \.php$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /opt/nginx/conf/fastcgi_params;
        }

        location ~ /\.ht {
                deny all;
        }

        if (-f $request_filename) {
                break;
        if (-f $document_root/system/maintenance.html) {
                rewrite ^(.*)$ /system/maintenance.html break;
        }

        error_page 500 502 503 504 /500.html;
        location = /500.html {
                root /home/deploy/xboxmma.com/current/public;
        }
}
</pre>
<p>Now that the boring php processing and routing stuff is out of the way, lets get into the important stuff and look how to integrate the authentication system of punBB and the Rails application.</p>
<p>The &#8220;trick&#8221; we will be using, is to manually set the login cookie for punBB whenever a user logs into the main website (we&#8217;ll delete the cookie as well when the user logs out).  The login cookie format has changed a bit since <a href="http://weblog.terrellrussell.com/2008/01/generating-a-rails-and-punbb-and-dokuwiki-shared-cookie/">Terrell&#8217;s writeup</a>, so I had to get my hands dirty and dig into the punBB PHP codebase to see exactly how they are setting their cookies.</p>
<p>First, add the following code to your application controller (or another controller if you don&#8217;t want/need the methods to be available everywhere).</p>
<pre class="brush: ruby;">
# RAILS_ROOT/app/controllers/application_controller.rb
  def set_shared_cookie
    return true unless Rails.env.production?
    require 'base64'
    expires = Time.now.to_i + 1209600

    begin
      # this sets the punbb cookie
      # it should be called on login from main site to allow unified login
      forumconfig = get_forum_config_data() # private method at bottom
      forumuser = ForumAccount.find_by_username( current_user.username )

      forum_hash = Digest::SHA1.hexdigest( forumuser.salt + Digest::SHA1.hexdigest( expires.to_s ) )
      cookie_value = &amp;quot;#{forumuser.id}|#{forumuser.password}|#{expires.to_s}|&amp;quot;
      cookie_value &amp;lt;&amp;lt; Digest::SHA1.hexdigest( &amp;quot;#{forumuser.salt}#{forumuser.password}#{forum_hash}&amp;quot; )

      cookies[forumconfig[:cookie_name]] = {
        :value =&amp;gt; Base64.encode64( cookie_value ),
        :expires =&amp;gt; 14.days.from_now
      }
    rescue =&amp;gt; e
      Rails.logger.warn &amp;quot;Problem setting punBB cookie #{e.message}&amp;quot;
    end
  end

  def clear_shared_cookie
    return true unless Rails.env.production?
    begin
      # should be called on logout from main site
      forumconfig = get_forum_config_data() # private method at bottom
      cookies[forumconfig[:cookie_name]] = nil
    rescue =&amp;gt; e
      Rails.logger.warn &amp;quot;Problem clearing punBB cookie #{e.message}&amp;quot;
    end
  end

  private

  # Uses regex to parse the php punbb config file
  # taken from: ahgsoftware.com/punbb_sdk/
  def get_forum_config_data
    config_hash = Hash.new
    c = File.read( File.join( RAILS_ROOT, 'config', 'config.php' ) )
    c.scan(/\$(\w*)\s*=\s*['&amp;quot;](.*)['&amp;quot;];/).each do |pair|
      config_hash[pair[0].to_sym] = pair[1]
    end
    config_hash
  end
</pre>
<p>The
<pre class="brush: plain; light: true;">#get_forum_config_data</pre>
<p> private method simply reads the punBB config.php file to get the forum configuration info. (Remember we copied the config.php file over in our capistrano deploy addition.)</p>
<p>Both the
<pre class="brush: plain; light: &quot;true&quot;;">#set_shared_cookie</pre>
<p> method and the
<pre class="brush: plain; light: true;">#clear_shared_cookie</pre>
<p> method will only run during production mode.  I don&#8217;t have punBB setup on my dev system.  If you run a staging server you probably want to change it to check
<pre class="brush: plain; light: true;">Rails.env.development?</pre>
<p> so that the method will also be processed on your staging server.</p>
<p>You&#8217;ll also notice I wrap everything in both methods in a
<pre class="brush: ruby; light: true;">begin ... rescue</pre>
<p> block.  I don&#8217;t want errors in the cookie creation/deletion to throw errors to the users, so I just log then gracefully for now.</p>
<p>Let&#8217;s do a quick run through on the #set_shared_cookie method.  First we set an integer expiration date to 14 days in the future (the default punBB cookie length).  Next we read the forum config data and find the existing user record from the punBB database via the ForumAccount model.  We&#8217;ll look at the ForumAccount model in a bit.  </p>
<p>Next we set the cookie value so it appears in the same format the punBB will expect when it reads the cookie back in and write the cookie to the session.</p>
<p>For XBoxMMA.com I use <a href="http://github.com/binarylogic/authlogic/tree/master">Authlogic</a> as the authentication system, so I call the set_shared_cookie method from my user_sessions controller after a new session is created.  I also call it from my users_controller when a new user is created.  I call the clear_shared_cookie method when the user logs out.</p>
<p>Now that we&#8217;ve seen how to make the shared cookie, lets look at the models used to access the punBB database tables.</p>
<p>I use a separate database for punBB instead of dumping the tables into my rails app DB, so I added an extra section to my
<pre class="brush: plain; light: true;">RAILS_ROOT/config/database.yml</pre>
<p> file.</p>
<pre class="brush: plain;">
forums_production:
  adapter: mysql
  database: xboxmma_forum
  username: xboxmma
  password: password
  host: localhost
  encoding: utf8
  socket: /var/run/mysqld/mysqld.sock
</pre>
<p>If you are using a staging environment, be sure to add a &#8220;forums_staging&#8221; section as well.</p>
<p>Next, I added two new models to access the punBB DB.</p>
<pre class="brush: ruby;">
# app/models/forum.rb
class Forum &amp;lt; ActiveRecord::Base
  self.abstract_class = true
  establish_connection &amp;quot;forums_#{Rails.env}&amp;quot;
end

# app/models/forum_account.rb
class ForumAccount &amp;lt; Forum
  set_table_name 'users' # add the table prefix if you set one in punBB

  def encrypt_and_save_new_password( _password )
    write_attribute( &amp;quot;password&amp;quot;, forum_hash( _password ) )
    save
  end

  private

  def forum_hash( _str )
    Digest::SHA1.hexdigest( self.salt + Digest::SHA1.hexdigest( _str ) )
  end

end
</pre>
<p>The
<pre class="brush: ruby; light: true;">#encrypt_and_save_new_password</pre>
<p> method should be called anytime your user updates their password in your Rails app.  This method will update their forum password at the same time and keep the two in sync.</p>
<p>Now you have Rails models setup that will be able to access your punBB DB (you will remember the ForumAccount model we referenced earlier in the set_shared_cookie method).</p>
<p>Everything should now be working for you.  Don&#8217;t forget to run the
<pre class="brush: plain; light: true;">admin/install.php</pre>
<p> script as well to setup your initial punBB configuration.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/how-to-integrate-punbb-into-an-existing-ruby-on-rails-application/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rails IE Bug with Excel Mime Types</title>
		<link>http://craigjolicoeur.com/blog/rails-ie-bug-with-excel-mime-types</link>
		<comments>http://craigjolicoeur.com/blog/rails-ie-bug-with-excel-mime-types#comments</comments>
		<pubDate>Thu, 28 May 2009 16:29:27 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[IE6]]></category>
		<category><![CDATA[IE7]]></category>
		<category><![CDATA[Internet Explorer]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=129</guid>
		<description><![CDATA[Another example of why IE is awful and a gotcha to lookout for in your Rails app]]></description>
			<content:encoded><![CDATA[<p>Came across a pretty interesting issue this week while trying to do some bugfixes for a project in IE6 and IE7.</p>
<p>The Rails project has one action that accepts an *.xls format to deliver an excel spreadsheet to the user.  Getting this to work is very simple, but for the sake of explanation here is the process.</p>
<p>Simply register the mime type in an initializer file</p>
<pre class="brush: ruby;">
# config/initializers/mime_types.rb
Mime::Type.register &quot;application/vnd.ms-excel&quot;, :xls
</pre>
<p>Then in your controller actions respond_to block you can simply reference the new format:</p>
<pre class="brush: ruby;">
# app/controllers/my_controller.rb
def my_action
  ...
  respond_to do |format|
    format.xls { send_file ... }
  end
end
</pre>
<p>Now, back to the &#8220;bug&#8221; or issue with IE6 and IE7.  Every time a user hit that specific action with a regular request (not requesting the *.xls format), they received both the expected HTML output AND the xls format output.  </p>
<p>Naturally, I don&#8217;t want to bombard the user when an IE popup boxing asking them to download and Excel file when they aren&#8217;t requesting it.</p>
<p>A quick trip to Google turned up <a href="http://dev.rubyonrails.org/ticket/9535">this old Rails ticket</a>.  The issue appears to be with how IE6 and IE7 set their HTTP_ACCEPT headers:</p>
<pre class="brush: plain;">
image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, */*
</pre>
<p>There are two easy work-around solutions.</p>
<p>First, you can manually check and set the format param for IE requests:</p>
<pre class="brush: ruby;">
before_filter :hijack_ie_default_format

def hijack_ie_default_format
  if request.user_agent =~ /MSIE/ and params['format'].nil?
    params['format'] = 'html'
  end
end
</pre>
<p>However, be careful when doing this.  If your action can also accept AJAX ( text/javascript ) requests, then this will override that as well and set the format to return as HTML which is obviously not what you want.  You would then end up spending a few hours wondering why IE6 and IE7 where returning javascript &#8220;Syntax Errors&#8221; on your AJAX actions.</p>
<p>What I ended up doing, since I needed that specific action to respond to javascript requests as well, was to simply extract the excel request into its own action.  Sure this may be overkill and not very DRY, but it is still a proper solution.  I just created a new #excel_export action and updated my excel links to point to the new action.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/rails-ie-bug-with-excel-mime-types/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Setting Static Asset Expires Headers with nginx and Passenger</title>
		<link>http://craigjolicoeur.com/blog/setting-static-asset-expires-headers-with-nginx-and-passenger</link>
		<comments>http://craigjolicoeur.com/blog/setting-static-asset-expires-headers-with-nginx-and-passenger#comments</comments>
		<pubDate>Wed, 20 May 2009 19:01:17 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[headers]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[passenger]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=125</guid>
		<description><![CDATA[How to set HTTP expires headers for your static assets when running nginx+passenger]]></description>
			<content:encoded><![CDATA[<p>On a recent project I launched, I&#8217;m using the combination <a href="http://www.modrails.com/install.html">nginx+passenger</a> for my front end my my Ruby on Rails application.</p>
<p>While trying to boost my <a href="http://developer.yahoo.com/yslow/">YSlow</a> score, I was having a bit of difficulty trying to figure out how to set HTTP expires headers on all the static assets served by my app.</p>
<p>Rails will set an internal time stamp on static assets (images, css files, javascript files, etc&#8230;) by appending a integer value onto the end of the asset filename</p>
<pre class="brush: plain; light: true;">http://mydomain.com/images/asset.png?12345678</pre>
<p>My original attempt at getting nginx to set an expires header for these assets had me adding the following location block to my nginx config file:</p>
<pre class="brush: plain;">
location ~* \.(ico|css|js|gif|jpe?g|png)\?[0-9]+$ {
    expires max;
    break;
}
</pre>
<p>The regexp I was using was incorrect however as it didn&#8217;t take into account that the ?timestamp might not exist in the URI.</p>
<p><a href="http://izumi.plan99.net/blog/">Hongli Lai</a> kindly pointed me in the right direction and showed me the proper regexp that he is using.</p>
<pre class="brush: plain;">
location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
    expires max;
    break;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/setting-static-asset-expires-headers-with-nginx-and-passenger/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Rails plugin install from specific git branch</title>
		<link>http://craigjolicoeur.com/blog/rails-plugin-install-from-specific-git-branch</link>
		<comments>http://craigjolicoeur.com/blog/rails-plugin-install-from-specific-git-branch#comments</comments>
		<pubDate>Tue, 19 May 2009 18:07:55 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[git]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[rubyonrails]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=100</guid>
		<description><![CDATA[How to install a rails plugin from a specific tag or branch in a git repository]]></description>
			<content:encoded><![CDATA[<p>Recently while working on a Ruby on Rails plugin, I came across the need to install the plugin from a specific git branch instead of the default master branch.</p>
<pre class="brush: bash; light: true;">
./script/plugin install -h
</pre>
<p>yielded the helpful information I needed.  Last July, <a href="http://github.com/rails/rails/commit/5c086070824bf7dd2bc4c9ce97956d82ac3fa206">a patch was committed</a> to Rails that added the -r ( or &#8211;revision ) parameter.</p>
<p>The -r parameter will take either the name of a git branch or a tag string to checkout instead of the default master branch.</p>
<p>So issuing the following command:</p>
<pre class="brush: bash; light: true;">
./script/plugin install git://github.com/cpjolicoeur/my_plugin.git -r BRANCH_NAME
</pre>
<p>will checkout the BRANCH_NAME branch of the git repository.</p>
<p>Very helpful when testing and debugging new features and bugfixes in a plugin. </p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/rails-plugin-install-from-specific-git-branch/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Getting Capistrano&#8217;s web:disable To Work With Nginx</title>
		<link>http://craigjolicoeur.com/blog/getting-capistranos-webdisable-to-work-with-nginx</link>
		<comments>http://craigjolicoeur.com/blog/getting-capistranos-webdisable-to-work-with-nginx#comments</comments>
		<pubDate>Sun, 17 May 2009 17:13:25 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=92</guid>
		<description><![CDATA[Recently I deployed a new Ruby on Rails application using nginx+passenger instead of the usual apache+passenger configuration.
As a result, I couldn&#8217;t use the traditional Apache rewrite rules to display the maintenance.html page if it existed.
Here are the necessary corresponding rewrite rules for nginx to achieve the same effect.

if (-f $document_root/system/maintenance.html) {
    rewrite [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I deployed a new Ruby on Rails application using <a href="http://www.modrails.com/install.html">nginx+passenger</a> instead of the usual apache+passenger configuration.</p>
<p>As a result, I couldn&#8217;t use the traditional Apache rewrite rules to display the maintenance.html page if it existed.</p>
<p>Here are the necessary corresponding rewrite rules for nginx to achieve the same effect.</p>
<pre class="brush: plain;">
if (-f $document_root/system/maintenance.html) {
    rewrite ^(.*)$ /system/maintenance.html break;
}
</pre>
<p>Place this inside your server {} block and you should be able to run cap deploy:web:disable and cap deploy:web:enable with no problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/getting-capistranos-webdisable-to-work-with-nginx/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BBRuby 0.8 Release</title>
		<link>http://craigjolicoeur.com/blog/bbruby-08-release</link>
		<comments>http://craigjolicoeur.com/blog/bbruby-08-release#comments</comments>
		<pubDate>Mon, 24 Nov 2008 20:32:41 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[bbcode]]></category>
		<category><![CDATA[BBRuby]]></category>
		<category><![CDATA[gem]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=79</guid>
		<description><![CDATA[Version 0.8 of the BBRuby gem was released today.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve updated and released version 0.8 of my the <a href="http://github.com/cpjolicoeur/bb-ruby/tree/master">BBRuby library</a> today.  Go ahead and grab the latest code from GitHub.</p>
<p>To download the newest gem just do the usual gem install: </p>
<pre class="brush: bash; light: true;">sudo gem install cpjolicoeur-bb-ruby --source=http://gems.github.com</pre>
<p>For those of you who want to use the library as a rails plugin, install like normal:</p>
<pre class="brush: bash; light: true;">./script/plugin install git://github.com/cpjolicoeur/bb-ruby.git</pre>
<p>The new version includes updated (and corrected) README docs as well as a better test suite.  Also, the :enable and :disable parameters should now be fully functional.  Sorry for the issues some of you reported with the prior version.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/bbruby-08-release/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Set RAILS_ENV for Phusion Passenger on Dreamhost</title>
		<link>http://craigjolicoeur.com/blog/set-rails_env-for-phusion-passenger-on-dreamhost</link>
		<comments>http://craigjolicoeur.com/blog/set-rails_env-for-phusion-passenger-on-dreamhost#comments</comments>
		<pubDate>Mon, 10 Nov 2008 22:07:10 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[dreamhost]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[mod_rails]]></category>
		<category><![CDATA[passenger]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=77</guid>
		<description><![CDATA[How to set RAILS_ENV for phusion passenger on your Dreamhost account.]]></description>
			<content:encoded><![CDATA[<p>Recently I began looking into using <a href="http://www.modrails.com/">Phusion Passenger</a> for running all my Rails apps instead of the normal nginx+mongrel stack that I normally use.  Since its release, Passenger has been getting quite a bit of publicity and hype and I figured it was time I started looking into it on my own as well.</p>
<p><a href="http://www.dreamhost.com/r.cgi?225041">Dreamhost</a> was the first shared hosting provider to offer Passenger on all their shared hosting plans so that was a natural place for me to start.  I planned on using my Dreamhost box as a staging server for a few small apps  as I started to get a feel for Passenger.</p>
<p>The major problem I ran into was trying to set RAILS_ENV to &#8220;staging&#8221; so that my apps would run from the staging environment.  The way Passenger gets configured, the RAILS_ENV setting is configured in the Apache virtual host file, which I don&#8217;t have access to on Dreamhost (or most other shared hosting providers).</p>
<p>You can set the RAILS_ENV constant in your config/environment.rb file to &#8217;staging&#8217; and Passenger will pick the setting up; but, of course, this won&#8217;t work because then I would be required to constantly manage and change my environment.rb file depending on whether or not I was working  locally in &#8216;development&#8217; or on &#8216;production.&#8217;</p>
<p>What I decided to do was just add a custom task to my <a href="http://www.capify.org/">capistrano</a> deployment recipe file (config/deploy.rb) and manually insert the RAILS_ENV variable into the top of my config/environment.rb file after deploy.</p>
<pre class="brush: ruby;">
namespace :deploy do
  desc &quot;set ENV['RAILS_ENV'] for mod_rails (phusion passenger)&quot;
  task :set_rails_env do
    tmp = &quot;#{current_release}/tmp/environment.rb&quot;
    final = &quot;#{current_release}/config/environment.rb&quot;
    run &lt;&lt;-CMD
      echo 'RAILS_ENV = &quot;#{rails_env}&quot;' &gt; #{tmp};
      cat #{final} &gt;&gt; #{tmp} &amp;&amp; mv #{tmp} #{final};
    CMD
  end
end

after &quot;deploy:finalize_update&quot;, &quot;deploy:set_rails_env&quot;
</pre>
<p>Now based on my cap deployment command, the RAILS_ENV will be set to &#8217;staging&#8217; or &#8216;production&#8217;  automatically.  Really, staging is all that I needed since production is the natural environment on my production server already.</p>
<p>Hope this helps and saves someone else an hour of searching.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/set-rails_env-for-phusion-passenger-on-dreamhost/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Rails 2.x In Place Editor</title>
		<link>http://craigjolicoeur.com/blog/rails-2x-in-place-editor</link>
		<comments>http://craigjolicoeur.com/blog/rails-2x-in-place-editor#comments</comments>
		<pubDate>Thu, 31 Jul 2008 18:21:32 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[in_place_editor]]></category>
		<category><![CDATA[rubyonrails]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/?p=58</guid>
		<description><![CDATA[A few Rails 2.x gotchas when using the in_place_editor plugin]]></description>
			<content:encoded><![CDATA[<p>I had the need to use the old in_place_editor functionality in a new Rails app that I&#8217;m working on.  I hadn&#8217;t used the functionality for a while now and using it in a Rails 2.x environment is a bit different than in a Rails 1.x environment so I thought I&#8217;d share what I found.</p>
<p>The in_place_editor functionality has been completed deprecated in the Rails 2.x codebase and now you need to install <a href="http://svn.rubyonrails.org/rails/plugins/in_place_editing/README">the plugin</a> to use the functionality.  To install the plugin use the following command from your rails root directory:</p>
<pre class="brush: bash;">
ruby script/plugin install http://svn.rubyonrails.org/rails/plugins/in_place_editing
</pre>
<p>Now, if you are using the new authenticity token features of Rails 2, the plugin won&#8217;t work for you out of the box.  First you will need to <a href="http://dev.rubyonrails.org/ticket/10055">apply this patch</a>.  It&#8217;s best to apply the patch even if you aren&#8217;t using the authenticity token feature just so you are &#8220;future-proof.&#8221;  I&#8217;m not sure why the plugin trunk hasn&#8217;t been updated with the patch already, but it hasn&#8217;t so you need to do it yourself.</p>
<p>Now you can use both the <code><a href="http://rails.rubyonrails.com/classes/ActionView/Helpers/JavaScriptMacrosHelper.html#M000575">in_place_editor</a></code> and <code><a href="http://rails.rubyonrails.com/classes/ActionView/Helpers/JavaScriptMacrosHelper.html#M000576">in_place_editor_field</a></code> helpers in your view files.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/rails-2x-in-place-editor/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Small Tweak to atom_feed_helper Plugin</title>
		<link>http://craigjolicoeur.com/blog/small-tweak-to-atom_feed_helper-plugin</link>
		<comments>http://craigjolicoeur.com/blog/small-tweak-to-atom_feed_helper-plugin#comments</comments>
		<pubDate>Fri, 07 Dec 2007 14:26:23 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[plugins]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[atom_feed_helper]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[polymorphic]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.craigjolicoeur.com/2007/12/07/small-tweak-to-atom_feed_helper-plugin/</guid>
		<description><![CDATA[I ran into an interesting &#8220;issue&#8221; this past week while using the atom_feed_helper plugin for Rails.
The plugin is designed to be a quick, easy-to-use way to generate ATOM feeds for your controllers.  An interesting issue with the plugin is that it doesn&#8217;t allow you to manually set each ATOM entries link URL.  The [...]]]></description>
			<content:encoded><![CDATA[<p>I ran into an interesting &#8220;issue&#8221; this past week while using the atom_feed_helper plugin for Rails.</p>
<p>The plugin is designed to be a quick, easy-to-use way to generate ATOM feeds for your controllers.  An interesting issue with the plugin is that it doesn&#8217;t allow you to manually set each ATOM entries link URL.  The plugin sets the link field manually using the _polymorphic_url()_ method.</p>
<pre class="brush: ruby;">
@xml.link(:rel =&gt; 'alternate', :type =&gt; 'text/html', :href =&gt; @view.polymorphic_url(record))
</pre>
<p>My problem with this arose when trying to generate a feed for a nested resource. I wanted to generate an ATOM feed for all Comments left on a certain Question in my Rails application.  Comments are not viewed individually, but rather as a threaded list in the Show method of the Question to which they belong.  The URL generated by the _polymorphic_url()_ call didn&#8217;t quite handle this properly.</p>
<p>The more I thought about this, I can see other instances as well where you might want to manually specify a certain URL for each entry link.  So I went about making the following change to the plugin and am going to be submitting the patch to the Rails team as an enhancement.</p>
<pre class="brush: ruby;">
def entry(record, link = nil)
  @xml.entry do
    @xml.id(&quot;tag:#{@view.request.host_with_port},2007:#{record.class}#{record.id}&quot;)
    @xml.published(record.created_at.xmlschema) if record.respond_to?(:created_at)
    @xml.updated(record.updated_at.xmlschema) if record.respond_to?(:updated_at)

    yield @xml

    entry_link = link.nil? ? @view.polymorphic_url(record) : link
    @xml.link(:rel =&gt; 'alternate', :type =&gt; 'text/html', :href =&gt; entry_link)
  end
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/small-tweak-to-atom_feed_helper-plugin/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gathering Wis.dm</title>
		<link>http://craigjolicoeur.com/blog/gathering-wisdm</link>
		<comments>http://craigjolicoeur.com/blog/gathering-wisdm#comments</comments>
		<pubDate>Sat, 15 Sep 2007 13:50:59 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.craigjolicoeur.com/2007/09/15/gathering-wisdm/</guid>
		<description><![CDATA[It&#8217;s now official.  I&#8217;ve left RatePoint and joined the team at Wis.dm.
I really enjoyed my time at RatePoint getting the company up and running.  Over the past 10 months we released 4 different Rails apps: a social website ratings service, a badge reputation service, an avatar rating service for SecondLife, and an API [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s now official.  I&#8217;ve left <a href="http://www.ratepoint.com">RatePoint</a> and joined the team at <a href="http://wis.dm">Wis.dm</a>.</p>
<p>I really enjoyed my time at RatePoint getting the company up and running.  Over the past 10 months we released 4 different Rails apps: a <a href="http://web.ratepoint.com">social website ratings service</a>, a <a href="http://www.ratepoint.com">badge reputation service</a>, an <a href="http://web.ratepoint.com/sl">avatar rating service for SecondLife</a>, and an API to automate signups for <a href="http://www.ratepoint.com/resellers">the badge reseller program</a>.</p>
<p>Wis.dm is another Ruby on Rails web startup that is taking on the question/answer space.  I&#8217;m excited to get started there and see where we can take the site.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/gathering-wisdm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
