<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Random Hacks: Tag Rails</title>
    <link>http://www.randomhacks.net/articles/tag/Rails?tag=Rails</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Technology and Other Fun Stuff</description>
    <item>
      <title>Screencast: Use Rails and RDF.rb to parse Best Buy product reviews</title>
      <description>&lt;p&gt;In the past few years, many companies have been embedding machine-readable metadata in their web pages. Among these is Best Buy, which &lt;a href="http://jay.beweep.com/category/rdfa/"&gt;provides extensive RDFa data&lt;/a&gt; describing their products, prices and user reviews.&lt;/p&gt;

&lt;p&gt;The following 20-minute screencast shows how to use Ruby 1.9.2, Rails 3.1rc1, &lt;a href="http://rdf.rubyforge.org/"&gt;RDF.rb&lt;/a&gt; and my &lt;a href="http://rdf-agraph.rubyforge.org/"&gt;rdf-agraph&lt;/a&gt; gem to compare user ratings of the iPad and various Android Honeycomb tablets.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2011/06/05/screencast-rails-rdf-agraph-product-reviews"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 05 Jun 2011 19:07:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:f2fc22a5-16da-46a9-96a2-999264effcf1</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2011/06/05/screencast-rails-rdf-agraph-product-reviews</link>
      <category>Ruby</category>
      <category>Rails</category>
      <category>RDF</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/850</trackback:ping>
    </item>
    <item>
      <title>Heroku &amp;quot;Celadon Cedar&amp;quot; review</title>
      <description>&lt;p&gt;Heroku just released a new version of their hosting service for Ruby on Rails. It&amp;#8217;s called &lt;a href="http://blog.heroku.com/archives/2011/5/31/celadon_cedar/"&gt;Celadon Cedar&lt;/a&gt;, and it adds support for arbitrary background processes, Node.js servers and long-polling over HTTP. &lt;/p&gt;

&lt;p&gt;I just finished porting a large Rails 3.0 application to Heroku&amp;#8217;s Ceder stack from &lt;a href="http://www.opscode.com/chef/"&gt;Chef&lt;/a&gt;+&lt;a href="http://aws.amazon.com/ec2/"&gt;EC2&lt;/a&gt;, and I&amp;#8217;m deeply impressed. But there are still some rough edges, especially with regard to asset caching.&lt;/p&gt;

&lt;h3&gt;Procfiles are really cool&lt;/h3&gt;

&lt;p&gt;Previous versions of Heroku could only run two types of processes: Web servers and &lt;a href="http://rubydoc.info/gems/delayed_job/2.1.4/frames"&gt;delayed_job&lt;/a&gt; workers. If you needed to monitor a ZeroMQ queue or run a cron job every minute, you were out of luck. So even though I loved Heroku, about 2/3rds of my clients couldn&amp;#8217;t even consider using it.&lt;/p&gt;

&lt;p&gt;Celadon Cedar, however, allows you to create a &lt;code&gt;Procfile&lt;/code&gt; specifying a list of process types to run:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;web:    bundle exec rails server -p $PORT
worker: bundle exec rake jobs:work
clock:  bundle exec clockwork config/clock.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once you&amp;#8217;ve deployed your project, you can specify how many of each process you want:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_sh "&gt;heroku scale web=3 worker=2 clock=1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Even better, if you&amp;#8217;re running on a development machine, or if you want to deploy to a regular Linux server, you can use the &lt;a href="http://adam.heroku.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/"&gt;Foreman&lt;/a&gt; gem to launch the processes manually, or to generate init scripts:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_sh "&gt;foreman start
foreman export upstart /etc/init -u username&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you&amp;#8217;re feeling more ambitious, you can also run &lt;a href="http://michaelvanrooijen.com/articles/2011/06/01-more-concurrency-on-a-single-heroku-dyno-with-the-new-celadon-cedar-stack/"&gt;Unicorn&lt;/a&gt; and &lt;a href="http://devcenter.heroku.com/articles/node-js"&gt;Node.js&lt;/a&gt; servers on Heroku.&lt;/p&gt;

&lt;h3&gt;Asset caching is even worse than before&lt;/h3&gt;

&lt;p&gt;Previous versions of Heroku had a built-in &lt;a href="http://www.varnish-cache.org/"&gt;Varnish cache&lt;/a&gt;, which would cache CSS, JavaScripts and images for 12 hours. The Varnish cache was automatically flushed on redeploy, so it gave you a nice performance boost for zero work.&lt;/p&gt;

&lt;p&gt;However, if you were running a high-performance site, you would generally want to run all your JavaScript and CSS through &lt;a href="http://developer.yahoo.com/yui/compressor/"&gt;YUI Compressor&lt;/a&gt;, which  vastly improves your download times. Under the previous version of Heroku, this was annoying to set up: You had to either commit your compiled assets into &lt;code&gt;git&lt;/code&gt;, or deploy them to a CDN manually.&lt;/p&gt;

&lt;p&gt;The Celadon Cedar stack, unfortunately, doesn&amp;#8217;t make it any easier to set up YUI Compressor, and it removes the existing Varnish cache. In place of Varnish, Heroku &lt;a href="http://devcenter.heroku.com/articles/http-caching"&gt;encourages you to set up Rack::Cache with memcached as a storage backend&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You may want to consider adding the following line to your &lt;code&gt;config.ru&lt;/code&gt; file, right before the &lt;code&gt;run&lt;/code&gt; statement:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;use&lt;/span&gt; &lt;span class="constant"&gt;Rack&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Deflater&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Combined with Rack::Cache, this will give you back some of the functionality of Varnish. But it&amp;#8217;s a lot more work than you needed to do before, and the results aren&amp;#8217;t as good. Heroku made this decision deliberately, because Varnish prevented them for doing cool things with Node.js servers and long-polled HTTP connections. But it still represents a retreat from Heroku&amp;#8217;s famous ease of use.&lt;/p&gt;

&lt;p&gt;What Heroku&amp;#8217;s Cedar stack really needs is first-class support for Rack::Cache, Rack::Deflator, and the new &lt;a href="http://www.rubyinside.com/how-to-rails-3-1-coffeescript-howto-4695.html"&gt;Sprockets asset caching in Rails 3.1&lt;/a&gt;. Please, just allow me to add a couple of lines to my &lt;code&gt;Gemfile&lt;/code&gt; and have everything work automagically. Yeah, you&amp;#8217;ve spoiled me and made me lazy.&lt;/p&gt;

&lt;h3&gt;You&amp;#8217;ll have to upgrade to Ruby 1.9.2&lt;/h3&gt;

&lt;p&gt;According to the &lt;a href="http://devcenter.heroku.com/articles/cedar#stack_software_versions"&gt;official documentation&lt;/a&gt;, only Ruby 1.9.2 is supported under Celadon Cedar. This isn&amp;#8217;t entirely surprising—Rails 3.1 recommends Ruby 1.9.2 as well—but it may be a problem for some users.&lt;/p&gt;

&lt;p&gt;Fortunately, my client&amp;#8217;s application worked flawlessly under Ruby 1.9.2 with only a single change to the &lt;code&gt;Gemfile&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Running a cron job once per minute is really easy, but it costs $71/month&lt;/h3&gt;

&lt;p&gt;One of Heroku&amp;#8217;s engineers explains how to run high-frequency cron jobs using &lt;a href="http://adam.heroku.com/past/2010/6/30/replace_cron_with_clockwork/"&gt;Clockwork&lt;/a&gt; and &lt;a href="http://rubydoc.info/gems/delayed_job/2.1.4/frames"&gt;delayed_job&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Basically, you add a couple of lines to your &lt;code&gt;Procfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;worker: bundle exec rake jobs:work
clock:  bundle exec clockwork config/clock.rb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&amp;#8230;and you put something like the following in &lt;code&gt;config/clock.rb&lt;/code&gt;:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;expand_path&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;../environment&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;  &lt;span class="constant"&gt;__FILE__&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span class="comment"&gt;# Run our heartbeat once per minute.&lt;/span&gt;
&lt;span class="ident"&gt;every&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;minutes&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;myapp.heartbeat&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="constant"&gt;MyApp&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;delay&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;heartbeat&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This creates a DelayedJob and hands it off to our worker process. According to the tutorial, you&amp;#8217;re supposed to do the actual work in a separate process, so as not to interfere with other events. This approach is elegant, but it&amp;#8217;s going to cost you $71/month for two &amp;#8220;dynos&amp;#8221;. Ouch.&lt;/p&gt;

&lt;h3&gt;Cedar is a great new stack, but it needs polishing&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;m really impressed with Celadon Cedar. Heroku has vastly improved their support for complex applications with a lot of moving parts. But along the way, they&amp;#8217;ve made it slightly harder to deploy simple applications, and they still don&amp;#8217;t have a painless way to do asset caching. Of course, these minor drawbacks should improve dramatically once the Ruby community plays with Cedar for a few weeks.&lt;/p&gt;

&lt;p&gt;Many thanks to Heroku for a great new release! I&amp;#8217;ll be moving more applications over soon.&lt;/p&gt;

&lt;p&gt;Does anybody have any suggestions on how make better use of Cedar and Rails?&lt;/p&gt;</description>
      <pubDate>Fri, 03 Jun 2011 19:20:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3df2e7b3-d7e1-4fe5-9468-ffa7596237a2</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2011/06/03/heroku-celadon-cedar-review</link>
      <category>Ruby</category>
      <category>Rails</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/849</trackback:ping>
    </item>
    <item>
      <title>The state of Ruby, RDF and Rails 3</title>
      <description>&lt;p&gt;Recently, I was investigating the state of RDF in the Ruby world.  Here are
some notes, in case anybody is curious.  I have used only a few of
these Ruby RDF libraries, so please feel free to add your own comments with
corrections and other alternatives.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s also some stuff about &lt;a href="http://rubyonrails.org/screencasts/rails3/active-relation-active-model"&gt;ActiveModel and ActiveRelation&lt;/a&gt; down at the end, for people who are interested in Rails 3.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2010/12/20/the-state-of-ruby-rdf-and-rails-3"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 20 Dec 2010 19:56:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:174f6eb6-ee3b-4c43-a665-b623fba65a63</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2010/12/20/the-state-of-ruby-rdf-and-rails-3</link>
      <category>Ruby</category>
      <category>RDF</category>
      <category>Rails</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/807</trackback:ping>
    </item>
    <item>
      <title>Selenium on Rails, Reloaded: Client-Side Tests in Ruby</title>
      <description>&lt;p&gt;Like most &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; developers, I write lots of test cases for
my models and controllers.  This lets me add new features quickly, without
worrying about breakage: My test cases act as a safety net, warning me
whenever existing code fails.&lt;/p&gt;

&lt;p&gt;Sadly, it&amp;#8217;s much harder to test client-side behavior.  Sure, you know your
controllers work, but what actually &lt;em&gt;happens&lt;/em&gt; if a user clicks the Submit
button?  We need a better way to test the system end-to-end, including the actual JavaScript and
web browsers.&lt;/p&gt;

&lt;p&gt;This article shows how to combine &lt;a href="http://www.openqa.org/selenium/"&gt;Selenium&lt;/a&gt;, &lt;a href="http://andthennothing.net/archives/2006/02/05/selenium-on-rails"&gt;Selenium on Rails&lt;/a&gt;, and a
&lt;a href="/files/rselenese.diff"&gt;custom patch&lt;/a&gt; to write client-side test cases in Ruby:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;setup&lt;/span&gt; &lt;span class="comment"&gt;# Load fixtures&lt;/span&gt;
&lt;span class="ident"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;open&lt;/span&gt; &lt;span class="symbol"&gt;:controller&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;customer&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
          &lt;span class="symbol"&gt;:action&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;list&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;assert_title&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Customers&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;click&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;myLink&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:wait&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
&lt;span class="ident"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;assert_title&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Customer: *&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;These test cases actually run in your browser, loading pages and clicking links just as a user would.  As the above example shows, you have full access to the Rails environment, including URL routing and configuration data.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2006/02/15/selenium-on-rails-reloaded"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 15 Feb 2006 08:06:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:55cb00a4-1da9-4bc4-9273-ca919579c458</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2006/02/15/selenium-on-rails-reloaded</link>
      <category>Rails</category>
      <category>Hacks</category>
      <category>Selenium</category>
      <category>testing</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/171</trackback:ping>
    </item>
    <item>
      <title>Moving a blog to Typo</title>
      <description>&lt;p&gt;This weekend, I moved Random Hacks to &lt;a href="http://typo.leetsoft.com/trac/"&gt;Typo&lt;/a&gt;, a nifty Rails-based blogging system. Here&amp;#8217;s what I did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up my Mac for Rails development&lt;/li&gt;
&lt;li&gt;Pointed Typo at MySQL&lt;/li&gt;
&lt;li&gt;Created a custom theme&lt;/li&gt;
&lt;li&gt;Wrote an article importer&lt;/li&gt;
&lt;li&gt;Routed my old URLs to new locations&lt;/li&gt;
&lt;li&gt;&lt;a href="http://randomhacks.net/articles/2005/11/13/typo-sidebars-recent-comments-and-tagged-articles"&gt;Wrote some custom sidebars&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Configured Debian&amp;#8217;s mod_fcgid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now for the gruesome details.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2005/11/15/moving-a-blog-to-typo"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 15 Nov 2005 22:13:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:e3f3c54b-6034-48f2-8949-d5e37a76558d</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2005/11/15/moving-a-blog-to-typo</link>
      <category>Rails</category>
      <category>Typo</category>
      <category>Ruby</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/76</trackback:ping>
    </item>
    <item>
      <title>Typo sidebars: Recent Comments and Tagged Articles</title>
      <description>&lt;p&gt;Here's two new plugins for &lt;a href="http://typo.leetsoft.com/trac/"&gt;Typo&lt;/a&gt;, the cool Rails-based blogging software. The first shows a &lt;a href="/files/recent_comments_sidebar.zip" title="Recent Comments Plugin"&gt;list of recent comments&lt;/a&gt;. The second shows &lt;a href="/files/tagged_articles_sidebar.zip" title="Tagged Articles Plugin"&gt;articles with a specific tag&lt;/a&gt;. (I use it to implement the "Recommended Reading" list in my sidebar.)&lt;/p&gt;

&lt;p&gt;To install the plugins, simply unzip them in your Typo root directory, restart Typo, and take a look at the "Sidebar" tab in the admin screen.&lt;/p&gt;

&lt;p&gt;These plugins were unbelievably simple to write. If you'd like to see how they work, keep reading.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2005/11/13/typo-sidebars-recent-comments-and-tagged-articles"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 13 Nov 2005 21:04:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:67f6b627-8a35-4c65-a1e2-1a0350e347aa</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2005/11/13/typo-sidebars-recent-comments-and-tagged-articles</link>
      <category>Typo</category>
      <category>Rails</category>
      <category>Hacks</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/74</trackback:ping>
    </item>
    <item>
      <title>Random Hacks is back online</title>
      <description>    &lt;p&gt;I just recovered the contents of this site after a two-year hiatus.
    I'm going to try to dig up some other old stuff, too.&lt;/p&gt;

    &lt;p&gt;I should really rebuild this whole site using Ruby on Rails and some
    Ajax goodness.  But that's going to have to wait until I ship some
    software at work and take care of other personal projects.&lt;/p&gt;</description>
      <pubDate>Tue, 11 Oct 2005 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:cf79983a-dc3f-43d8-9522-b840329faef7</guid>
      <author>Eric</author>
      <link>http://www.randomhacks.net/articles/2005/10/11/back-online</link>
      <category>Ruby</category>
      <category>Rails</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/71</trackback:ping>
    </item>
  </channel>
</rss>

