<?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>Pervasive Code &#187; ruby on rails</title>
	<atom:link href="http://www.pervasivecode.com/blog/category/ruby-on-rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pervasivecode.com/blog</link>
	<description>Jamie Flournoy's Software Development Blog</description>
	<lastBuildDate>Mon, 26 Jul 2010 05:29:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How to make Machinist and Autotest coexist</title>
		<link>http://www.pervasivecode.com/blog/2010/03/23/how-to-make-machinist-and-autotest-coexis/</link>
		<comments>http://www.pervasivecode.com/blog/2010/03/23/how-to-make-machinist-and-autotest-coexis/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 03:47:22 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[agile development]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=189</guid>
		<description><![CDATA[If you&#8217;ve tried to use Machinist and autotest (part of ZenTest) you have probably seen this exception that prevented you from using it: 
`method_missing': No sham defined for name
It&#8217;s discussed in the machinist Google Group as well.
It&#8217;s because of a wacky hack that&#8217;s part of Machinist that overrides Module.name so you can do Sham.name, but [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve tried to use Machinist and autotest (part of ZenTest) you have probably seen this exception that prevented you from using it: </p>
<pre>`method_missing': No sham defined for name</pre>
<p>It&#8217;s discussed in <a href="http://groups.google.com/group/machinist-users/browse_thread/thread/9af4aa2243ae0368/4e9bba83113ace20">the machinist Google Group</a> as well.</p>
<p>It&#8217;s because of a wacky hack that&#8217;s part of Machinist that overrides Module.name so you can do <code>Sham.name</code>, but ZenTest expects Module.name to do what it does normally.</p>
<p>I have a fix for this.<br />
<span id="more-189"></span></p>
<p>I sent notahat a pull request via GitHub, so hopefully it&#8217;ll be merged by notahat into the official machinist gem, but until that happens you can try mine. I published the gem as JamieFlournoy-machinist to rubygems.org.</p>
<p>Try &#8216;gem install JamieFlournoy-machinist -v 1.0.6&#8242; and see if it works for you. It does for me with ZenTest 4.2.1, autotest-rails 4.1.0, and a Rails 2.3.5 project.</p>
<p><a href="http://github.com/JamieFlournoy/machinist">(my machinist fork on github)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/03/23/how-to-make-machinist-and-autotest-coexis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails Migration Antipatterns and How To Fix Them</title>
		<link>http://www.pervasivecode.com/blog/2010/03/18/rails-migration-antipatterns-and-how-to-fix-them/</link>
		<comments>http://www.pervasivecode.com/blog/2010/03/18/rails-migration-antipatterns-and-how-to-fix-them/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 11:29:40 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=171</guid>
		<description><![CDATA[Migrations are one of the best features of Rails. Although some folks prefer pure SQL rather than Rails migration DSL, I don&#8217;t know of anyone who dislikes the idea of a versioned schema that can evolve in a controlled and repeatable fashion.
But because the concept of database migrations is such a powerful one, it&#8217;s tempting [...]]]></description>
			<content:encoded><![CDATA[<p>Migrations are one of the best features of Rails. Although some folks prefer pure SQL rather than Rails migration DSL, I don&#8217;t know of anyone who dislikes the idea of a versioned schema that can evolve in a controlled and repeatable fashion.</p>
<p>But because the concept of database migrations is such a powerful one, it&#8217;s tempting to jam any old change that affects the database into a new migration and run <code>rake db:migrate</code> to make it happen. I&#8217;ve been guilty of a bit of this in the past, and I&#8217;ve joined some projects that did other ugly things in migrations. In the process I&#8217;ve learned the hard way that there are some things you <b>must never do</b> in a migration or they will come back to haunt you later. Here they are.<br />
<span id="more-171"></span></p>
<h3>Antipattern: Require the Database to Exist Already</h3>
<p>In other words, the antipattern is for the first migration to depend on some tables and maybe even some data already being in the database.</p>
<p>I know that the original Rails blog video shows DHH using a MySQL admin tool to create the blog database interactively, but really you should be using migrations to create the schema programmatically from scratch.</p>
<p>If you&#8217;re already working on a project that didn&#8217;t do that, you can run <code>rake db:schema:dump</code> and look at db/schema.rb; it contains code that you can insert into a new migration to create the same schema in your development environment. If you&#8217;re using DB features that the design philosophy of ActiveRecord doesn&#8217;t agree with, such as triggers, and the schema.rb dump doesn&#8217;t include them (or if you just think the migration DSL is ugly and you like SQL DDL better), you can do a mysqldump / pg_dump / whateverdump and wrap a migration around the loading of that SQL file.</p>
<p>If you have a hybrid (you have to start with an old db dump and then migrate it so it becomes current), that&#8217;s gross, and you have a couple of options which are both pretty ugly. But they will work, and when you&#8217;re done the ugliness will be gone.</p>
<p>You could fight your way back to the oldest schema version by debugging the <code>self.down</code> methods and running <code>rake db:rollback</code> repeatedly until you can create a <code>00001_starting_db_schema.rb</code> migration, or you could just blow away all the migrations and use the highest schema version for a new migration that contains the output of a current <code>rake db:schema:dump</code>. It depends on how many copies of the database are out there with old schemas that would need to be brought up to date. Clearing out db/migrate and replacing it all with a single migration is cleaner, but if your production database is 5 migrations out of date you obviously can&#8217;t do that. But you could collapse it down to the one big-bang migration (as the oldest), plus the 5 pending schema changes. If you do it right, you can just deploy the new code and run <code>rake db:migrate</code> and everything will be fine. If not, well, you were testing it on a backup of the production database, right? :)</p>
<h3>Antipattern: Only Work Correctly With the Production Data</h3>
<p>What&#8217;s wrong with developers just making dumps of the production database and loading them locally?</p>
<p>First of all, it means that all schema changes have to start at the production database and work backwards to developers&#8217; sandboxed development environments. Hopefully this strikes you as a very stupid workflow.</p>
<p>Secondly, maybe your users don&#8217;t all want to get a message that says &#8220;test message foo bar sdfasdfasd bloopity bloop&#8221; when you&#8217;re testing your new alert system. Should you really be putting their data (passwords, contact info, etc.) at the mercy of your crummy new code?</p>
<p>You should be able to immediately generate an empty, clean database for development. <code>rake db:drop; rake db:create; rake db:migrate</code> should do this; <code>rake db:reset</code> should have the same result but should be faster since it doesn&#8217;t bother with each migration in sequence.</p>
<p>You should also be able to immediately generate any essential base data such as the initial admin user. The <a href="http://github.com/mbleigh/seed-fu">SeedFu</a> plugin does a good job here.</p>
<p>If you need some additional fake data to fiddle around with in your development environment, the <a href="http://github.com/ryanb/populator">Populator</a> gem is handy for mass-inserting a bunch of faux data, especially in conjunction with <a href="http://faker.rubyforge.org/">Faker</a>.</p>
<p>Note that the migrations should neither depend on nor contain actual data. They should just change the data model.</p>
<h3>Antipattern: Clean Up That Only Works on Production Data</h3>
<p>This is really a subset of the previous item but it&#8217;s worth considering as a special case.</p>
<p>If you want to fix some data that got slightly corrupted by some bad code that has been replaced, migrations aren&#8217;t a terrible way to accomplish that.</p>
<p>It&#8217;s not really what migrations are for, and a one-off rake task can do it just as well, but if you really want to, you can get away with it under one condition: you have to make your cleanup migration code succeed even if the database is empty (such as when a developer has just run <code>rake db:reset; rake db:migrate</code>).</p>
<h3>Antipattern: Load Data</h3>
<p>The <a href="http://github.com/ryanb/populator">populator</a> gem is good for initial, mandatory data. The <a href="http://github.com/notahat/machinist">machinist</a> gem is good for synthetic test data. Delete db/fixtures and everything in it. Fixtures are evil.</p>
<p>Wrap a rake task around the &#8220;get my development database ready&#8221; concept. This task should start with the &#8220;get my empty production database ready&#8221; task (or some subset of that which is appropriate for developer use).</p>
<p>If you need to load arbitrary data now and then, write an importer. Do this as a rake task, or a web UI to a bulk data importer feature. Better yet, make a web UI in your admin area which is just a wrapper around the rake task that bulk imports data. Then delegate the bulk importing to your customers so your admins can do real admin work. But don&#8217;t load data in a migration.</p>
<h3>Antipattern: Use Rails Models in the Migration</h3>
<p>Models evolve, but old migrations don&#8217;t change (nor should they). So when you wrote a migration that used a model, it used the old version of the model code. Then a year later the model has evolved, and the new validations on first_name and last_name fail because it used to be full_name, and that old migration that hasn&#8217;t changed has stopped working. It depended on something that did change, incompatibly.</p>
<p>For rockstar points, in your continuous integration environment you should run <code>rake db:drop; rake db:create; rake db:migrate</code> to make sure that this can never happen.</p>
<p>But if it has already happened, rip out the model code and replace it with Rails DSL code, with execute statements containing raw SQL code, or (if you feel like a Ruby rockstar) declare new, stripped down model classes inside your migration class that will act as stand-ins for the limited needs of the migration. See <a href="http://toolmantim.com/thoughts/migrating_with_models">Migrating with Models</a> for more on how to do this last trick.</p>
<h3>Conclusion</h3>
<p>You should always be able to do this in every Rails environment that your application has: <code>rake db:drop; rake db:create; rake db:migrate; rake db:reset</code></p>
<p>At this point you should then be able to run <code>rake db:test:prepare</code> and then <code>rake spec</code> or <code>rake test</code> or whatever and have it work.</p>
<p>If any part of that process fails, you are missing out on the benefits of using Rails migrations.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/03/18/rails-migration-antipatterns-and-how-to-fix-them/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Making Bundler 0.8.5 install Nokogiri on Leopard with a newish libxml</title>
		<link>http://www.pervasivecode.com/blog/2010/03/17/making-bundler-0-8-5-install-nokogiri-on-leopard-with-a-newish-libxml/</link>
		<comments>http://www.pervasivecode.com/blog/2010/03/17/making-bundler-0-8-5-install-nokogiri-on-leopard-with-a-newish-libxml/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 01:03:34 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=166</guid>
		<description><![CDATA[Nokogiri on a standard installation of Leopard is complain-y about a couple of old libraries:
&#8220;HI.  You&#8217;re using libxml2 version 2.6.16 which is over 4 years old and has plenty of bugs.  We suggest that for maximum HTML/XML parsing pleasure, you upgrade your version of libxml2 and re-install nokogiri.  If you like using [...]]]></description>
			<content:encoded><![CDATA[<p>Nokogiri on a standard installation of Leopard is complain-y about a couple of old libraries:</p>
<p>&#8220;HI.  You&#8217;re using libxml2 version 2.6.16 which is over 4 years old and has plenty of bugs.  We suggest that for maximum HTML/XML parsing pleasure, you upgrade your version of libxml2 and re-install nokogiri.  If you like using libxml2 version 2.6.16, but don&#8217;t like this warning, please define the constant I_KNOW_I_AM_USING_AN_OLD_AND_BUGGY_VERSION_OF_LIBXML2 before requring nokogiri.&#8221;</p>
<p>Aaron Kalin <a href="http://martinisoftware.com/2009/07/31/nokogiri-on-leopard.html">figured out how to fix this if you&#8217;re installing nokogiri as a system gem</a>, but I want to use Bundler and keep my system gems down to the bare minimum. I figured out how to do this under Bundler 0.8.5.<br />
<span id="more-166"></span></p>
<p>The gems I have installed via plain old &#8220;gem install xxx&#8221; are bundler08 -v0.8.5, rake -v0.8.7, and ZenTest -v4.2.1. That&#8217;s it. Everything else is under vendor/bundler. I&#8217;m using <a href="http://rvm.beginrescueend.com/">RVM</a> and REE 1.8.7 2009.10 as described in <a href="http://www.pervasivecode.com/blog/2010/03/16/using-rvm-to-install-ree-1-8-7-2009-10/">my previous post</a>.</p>
<p>Here is a quick summary of Aaron&#8217;s blog post; this will update your libxml and libxslt libraries to reasonably recent versions. (Be my guest if you want to use libxml 2.7.7 and libxslt 1.1.26, which are current as of today, but I didn&#8217;t test those myself.)</p>
<pre>
mkdir -p ~/Downloads/XML
cd ~/Downloads/XML
curl -O ftp://xmlsoft.org/libxml2/libxml2-2.7.3.tar.gz
curl -O ftp://xmlsoft.org/libxml2/libxslt-1.1.24.tar.gz
tar xzf libxml2-2.7.3.tar.gz
tar xzf libxslt-1.1.24.tar.gz
cd ~/Downloads/XML/libxml2-2.7.3
./configure
nice make
sudo make install
cd ~/Downloads/XML/libxslt-1.1.24
./configure --with-libxml-prefix=/usr/local --with-libxml-include-prefix=/usr/local/include --with-libxml-libs-prefix=/usr/local/lib
nice make
sudo make install
</pre>
<p>Now make this YAML file and call it bundler_build_options_macosx_leopard.yml and put it in your RAILS_ROOT:</p>
<pre>
nokogiri:
  xml2-include: /usr/local/include/libxml2
  xml2-lib: /usr/local/lib
</pre>
<p>Then, to build nokogiri so that it uses the new libs you just installed:</p>
<pre>
gem bundle --build-options bundler_build_options_macosx_leopard.yml
</pre>
<p>You should now have nokogiri installed under vendor/bundler/ruby/1.8/gems, and when you run your app it should not complain about the version of libxml2 anymore.</p>
<p><b>Update:</b> Bundler 1.0.0.beta.10 allows this too. See my <a href="http://www.pervasivecode.com/blog/2010/07/25/making-bundler-1-0-0-beta-10-install-nokogiri-on-leopard-with-a-newish-libxml/">other post</a> that shows how to do it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/03/17/making-bundler-0-8-5-install-nokogiri-on-leopard-with-a-newish-libxml/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tidier HTTP error responses in Rails controllers</title>
		<link>http://www.pervasivecode.com/blog/2009/07/27/tidier-http-error-responses-in-rails-controllers/</link>
		<comments>http://www.pervasivecode.com/blog/2009/07/27/tidier-http-error-responses-in-rails-controllers/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 04:58:10 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=122</guid>
		<description><![CDATA[Rails provides some flexible and fairly short controller methods for responding with an HTTP error code. Given that controllers are complicated enough by nature, I&#8217;m always looking for ways to DRY them up and make the code easy to understand. So here are some controller methods that make it really easy to provide correct HTTP [...]]]></description>
			<content:encoded><![CDATA[<p>Rails provides some flexible and fairly short controller methods for responding with an HTTP error code. Given that controllers are complicated enough by nature, I&#8217;m always looking for ways to DRY them up and make the code easy to understand. So here are some controller methods that make it really easy to provide correct HTTP error responses to clients.<br />
<span id="more-122"></span></p>
<p>Put this in config/initializers/respond_with_http_errors.rb :</p>
<pre><code>
class ActionController::Base

  protected

  # Display a "400 Bad Request" response based on a determination made by application logic.
  def respond_bad_request(message = "Your request was invalid.", options = {})
    respond_with_error(400, 'Bad Request', message, options)
  end

  # Display a "403 Forbidden" response based on a determination made by application logic.
  def respond_forbidden(message = "You are not authorized to access that document.", options = {})
    respond_with_error(403, 'Forbidden', message, options)
  end

  # Display a "404 Not Found" response based on a determination made by application logic.
  def respond_not_found(message = "The document you requested doesn't exist.", options = {})
    respond_with_error(404, 'Not Found', message, options)
  end

  def respond_with_error(status_code, status_name, message, options)
    flash[:error] = message
    defaults = { :status =&gt; status_code }
    respond_to do |format|
      format.html { defaults.merge!(:inline =&gt; "&lt;h1&gt;#{status_name}&lt;/h1&gt;&lt;p&gt;&lt;%=h flash[:error] %&gt;&lt;/p&gt;", :layout =&gt; true) }
      format.json { defaults.merge!(:json =&gt; "#{status_name}: #{message}".to_json) }
    end
    render defaults.merge(options)
  end

end
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2009/07/27/tidier-http-error-responses-in-rails-controllers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Proper Error Handling in Rails Controllers</title>
		<link>http://www.pervasivecode.com/blog/2009/07/27/proper-error-handling-in-rails-controllers/</link>
		<comments>http://www.pervasivecode.com/blog/2009/07/27/proper-error-handling-in-rails-controllers/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 04:56:24 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=131</guid>
		<description><![CDATA[Rails controllers can get out of hand if you&#8217;re not very careful. Skinny Controller Fat Model is a great start. But what about handling errors? Isn&#8217;t it enough to just let Rails catch your exception and show a 500 Server Error page?
No, it&#8217;s not. Falling back on 500 Server Error for everything outside of the [...]]]></description>
			<content:encoded><![CDATA[<p>Rails controllers can get out of hand if you&#8217;re not very careful. <a href="http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model">Skinny Controller Fat Model</a> is a great start. But what about handling errors? Isn&#8217;t it enough to just let Rails catch your exception and show a 500 Server Error page?</p>
<p>No, it&#8217;s not. Falling back on 500 Server Error for everything outside of the &#8220;happy path&#8221; through your code is sloppy coding.<br />
<span id="more-131"></span><br />
I say this for three reasons:</p>
<p><b>The 5xx response codes are for server-side errors.</b></p>
<p>If the code is working properly but the request is wrong (no such document, an invalid request, or insufficient user privileges for the requested operation), the 4xx response codes are more appropriate. You should only return a 5xx series error message when your application is broken.</p>
<p><b>A generic &#8220;oops&#8221; page hides the cause of the error from the user.</b></p>
<p>Maybe the user followed a bad link, that goes to a document that has been deleted. They should see a 404 Not Found response, not a 500 Server Error. This is especially important if the user agent is a web service client actively under development. And remember that you can still customize the response body, so a 404 can show a search or site map to help them find the content that was Not Found, and a 403 might suggest that the user upgrade their subscription so they can see the Forbidden content.</p>
<p><b>Failing to trap bogus input is a recipe for a security vulnerability.</b></p>
<p>Rails will detect ridiculous input in many cases, but it doesn&#8217;t know about your business rules.</p>
<p>For example, what if someone fires up Firebug and figures out your API, and deletes her ex-boyfriend&#8217;s account because you forgot to check that the ID being deleted matches the currently logged in user? Oops.</p>
<p>You know who else got pwn3d because they put their security rules in the client? AOL. Don&#8217;t be like AOL. They got <a href="http://en.wikipedia.org/wiki/AOHell">pwn3d big time</a>. Make sure your controller handles the &#8220;unhappy path&#8221; too, and responds appropriately.</p>
<p>You make sure your controller handles these cases by writing tests, and checking that the response is correct. To do this, you need unambiguous errors that clearly explain what the controller didn&#8217;t like about the request. </p>
<p>Your controller tests should <i>never</i> expect an exception. Exceptions belong inside the application (such as between a model and a controller), not at the boundary.</p>
<p>Instead, you should be using something like <code>assert_response :bad_request</code>, and providing a useful textual message in the page that will help the user understand what they did wrong.</p>
<p>A nice bonus of using the right HTTP error responses is that your tests are more readable. And since controller tests tend to be really verbose already (mine tend to be ~10x as many LOC as the controller itself), the extra readability is really nice.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2009/07/27/proper-error-handling-in-rails-controllers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A Cucumber step to test for a YM4R Google Map</title>
		<link>http://www.pervasivecode.com/blog/2009/07/27/a-cucumber-step-to-test-for-a-ym4r-google-map/</link>
		<comments>http://www.pervasivecode.com/blog/2009/07/27/a-cucumber-step-to-test-for-a-ym4r-google-map/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 03:34:46 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=116</guid>
		<description><![CDATA[I had some problems with a view in a Rails app that was conditionally hiding a Google Map that was generated using the YM4R plugin. I don&#8217;t usually test views in unit tests, and this logic depended on a particular situation with the data behind the view, so I decided that this would be a [...]]]></description>
			<content:encoded><![CDATA[<p>I had some problems with a view in a Rails app that was conditionally hiding a Google Map that was generated using the <a href="http://ym4r.rubyforge.org/">YM4R</a> plugin. I don&#8217;t usually test views in unit tests, and this logic depended on a particular situation with the data behind the view, so I decided that this would be a good candidate for a Cucumber feature.</p>
<p>Here&#8217;s the Cucumber step implementation I wrote.<br />
<span id="more-116"></span><br />
Put this in a new file called features/step_definitions/ym4r_gm_steps.rb :</p>
<pre>
# Steps for use with the ym4r_gm plugin

Then /^I should see a Google Map$/i do
  within 'head' do
    ['http://maps.google.com/maps', '/javascripts/ym4r-gm.js'].each do |js_url|
      assert_have_xpath "//script[starts-with(@src, '#{js_url}')]"
    end
  end
  assert_select '#map_div'
end
</pre>
<p>This assumes that you let the plugin installer put the .js file in the default location, and that you have your Google Map inside #map_div.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2009/07/27/a-cucumber-step-to-test-for-a-ym4r-google-map/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fancier Stubbing of GeoKit for Rails unit tests</title>
		<link>http://www.pervasivecode.com/blog/2009/07/23/fancier-stubbing-of-geokit-for-rails-unit-tests/</link>
		<comments>http://www.pervasivecode.com/blog/2009/07/23/fancier-stubbing-of-geokit-for-rails-unit-tests/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 00:00:44 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[process]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=108</guid>
		<description><![CDATA[I&#8217;m working on a Rails app that uses the ym4r_gm plugin, getting Google to do the geocoding for Thentic. I liked the idea of stubbing the web service call, because all those calls to an external service add up to over 20 seconds of test suite run time(!). That&#8217;s almost half of the 50 second [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a Rails app that uses the ym4r_gm plugin, getting Google to do the geocoding for <a href="http://www.thentic.com/">Thentic</a>. I liked the idea of stubbing the web service call, because all those calls to an external service add up to over 20 seconds of test suite run time(!). That&#8217;s almost half of the 50 second run time of my unit tests (and 50 seconds is much too long for a unit test suite).</p>
<p>I found a good starting point at <a href="http://beardendesigns.com/blogs/permalink/55">geokit stubbing for faster tests</a>. I also wanted a way to stub a geocoding failure, and a way to prevent any unit tests from using the real geocoding web service.</p>
<p>Here&#8217;s how I did it.<br />
<span id="more-108"></span><br />
In test/test_helper.rb, add this:</p>
<pre>
class ActiveSupport::TestCase
  def setup
    GeoKit::Geocoders::MultiGeocoder.stubs(:geocode).raises(RuntimeError,
      'Use mock_geocoding_success! or mock_geocoding_failure! in your test')
  end

  def mock_geocoding_success!
    geocode_payload = GeoKit::GeoLoc.new(:lat => 123.456, :lng => 123.456)
    geocode_payload.success = true
    GeoKit::Geocoders::MultiGeocoder.expects(:geocode).returns(geocode_payload)
  end

  def mock_geocoding_failure!
    geocode_payload = GeoKit::GeoLoc.new
    geocode_payload.success = false
    GeoKit::Geocoders::MultiGeocoder.expects(:geocode).returns(geocode_payload)
  end
end
</pre>
<p>What this does is to force you to choose either one of those mock_geocoding methods before you call the geocode method. To me this seems like a good idea since the integration tests that exercise the full application stack should probably be written using Cucumber and Webrat (which is what I&#8217;m using).</p>
<p>You will probably want to merge my one-line setup method into your existing setup code in test_helper, if any. Also note that this uses <a href="http://mocha.rubyforge.org/">Mocha</a> for mocking.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2009/07/23/fancier-stubbing-of-geokit-for-rails-unit-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extreme Programming Experiences: Conclusion</title>
		<link>http://www.pervasivecode.com/blog/2009/05/30/xp-experiences-conclusion/</link>
		<comments>http://www.pervasivecode.com/blog/2009/05/30/xp-experiences-conclusion/#comments</comments>
		<pubDate>Sat, 30 May 2009 07:21:15 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Extreme Programming (XP)]]></category>
		<category><![CDATA[agile development]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=94</guid>
		<description><![CDATA[Now that I&#8217;ve worked in a team that really was doing XP (except for our Lack Of Onsite Customer shortcoming) I can say that it works pretty well, but only to the extent that you do all of the practices together. Of course, that&#8217;s what the XP folks said from the beginning: you can&#8217;t just [...]]]></description>
			<content:encoded><![CDATA[<p>Now that I&#8217;ve worked in a team that really was doing XP (except for our Lack Of Onsite Customer shortcoming) I can say that it works pretty well, but only to the extent that you do <b>all</b> of the practices together. Of course, that&#8217;s what the XP folks said from the beginning: you can&#8217;t just apply 1% of it and make a judgement about it.<br />
<span id="more-94"></span><br />
With the recent resurgence of the XP methodology in the Ruby on Rails community (particularly in companies affiliated with Pivotal Labs), I expect a whole new flurry of related controversy. Hopefully with the experiences and advice I&#8217;ve given, this time we can avoid some of the confusion and skepticism, and actually adopt it where it makes sense.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2009/05/30/xp-experiences-conclusion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extreme Programming Experiences: Introduction</title>
		<link>http://www.pervasivecode.com/blog/2009/05/30/xp-experiences-introduction/</link>
		<comments>http://www.pervasivecode.com/blog/2009/05/30/xp-experiences-introduction/#comments</comments>
		<pubDate>Sat, 30 May 2009 06:32:51 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Extreme Programming (XP)]]></category>
		<category><![CDATA[agile development]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=88</guid>
		<description><![CDATA[Extreme Programming Experiences: Introduction
Over the last six months I&#8217;ve had the privilege of working in a software development team that was practicing the closest thing to a full implmentation of XP that I&#8217;ve ever seen.

This team was incubated in Pivotal Labs, who are experts at the Ruby on Rails software framework and the XP methodology.
I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>Extreme Programming Experiences: Introduction</p>
<p>Over the last six months I&#8217;ve had the privilege of working in a software development team that was practicing the closest thing to a full implmentation of <a href="http://en.wikipedia.org/wiki/Extreme_Programming">XP</a> that I&#8217;ve ever seen.<br />
<span id="more-88"></span><br />
This team was incubated in <a href="http://www.pivotallabs.com/">Pivotal Labs</a>, who are experts at the <a href="http://rubyonrails.org/">Ruby on Rails</a> software framework and the XP methodology.</p>
<p>I&#8217;ve read a lot about XP over the last ten years, and tried some of the <a href="http://c2.com/cgi/wiki?ExtremeProgrammingCorePractices">practices</a> when it seemed to make sense for the project I was working on at the time. I&#8217;ve tended to feel a mix of curious optimism and curmudgeonly skepticism toward some of the practices: could these ideas really work?</p>
<p>Well, I have tried to think critically in my analysis of fuzzy topics like <a href="http://www.pervasivecode.com/blog/2007/01/10/rapid-application-development-vs-big-design-up-front/">how much design to do</a>, so that I could figure out not whether something was a universally Great Idea or not, but rather when it would work well and when it wouldn&#8217;t. The only way to find out for sure is to try them.</p>
<p>Well, now I&#8217;ve worked in an XP shop and I&#8217;ve learned a lot about how to make XP work, and about the challenges that a team following an agile methodology faces. Here are the most important things I&#8217;ve learned, in the next few posts (broken up by topic to help keep the comments focused).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2009/05/30/xp-experiences-introduction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Things I had to fix for Rails 2.2.2</title>
		<link>http://www.pervasivecode.com/blog/2008/11/29/things-i-had-to-fix-for-rails-222/</link>
		<comments>http://www.pervasivecode.com/blog/2008/11/29/things-i-had-to-fix-for-rails-222/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 01:57:06 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=85</guid>
		<description><![CDATA[The new features in Ruby on Rails 2.2.2 have been well documented, and I&#8217;m looking forward to using several of them on WhatYouAte.com. If you&#8217;re reading this you probably are too.
However, if you&#8217;re upgrading an existing project and you&#8217;re sticking with official releases (as opposed to edge Rails) like I am, your code probably needs [...]]]></description>
			<content:encoded><![CDATA[<p>The new features in Ruby on Rails 2.2.2 have been <a href="http://www.rubyinside.com/rails-22-released-27-links-and-resources-to-get-you-going-1354.html">well documented</a>, and I&#8217;m looking forward to using several of them on <a href="http://www.whatyouate.com/">WhatYouAte.com</a>. If you&#8217;re reading this you probably are too.</p>
<p>However, if you&#8217;re upgrading an existing project and you&#8217;re sticking with official releases (as opposed to edge Rails) like I am, your code probably needs some tweaking to work with Rails 2.2.2. Mine certainly did. Although there were a lot of failed tests with ugly stacktraces, there were only a few API changes in Rails that needed to be accomodated to fix them all. Here&#8217;s a list of the changes that broke my app, and what I had to do to get it working again.<br />
<span id="more-85"></span></p>
<p><code>TextHelper.truncate</code> no longer allows you to supply the length parameter as a second argument. You have to use <code>truncate(somestring, :length => 20)</code> instead of <code>truncate(somestring, 20)</code>.</p>
<p>I was getting an error that looked like this:</p>
<pre>ActionView::TemplateError: wrong number of arguments (3 for 1)</pre>
<p>The line in question is:</p>
<pre>
&lt;%= render(:partial => 'layouts/header') %&gt;
</pre>
<p>The problem is that the simply_helpful plugin&#8217;s behavior is now built-in; just delete the whole vendor/plugins/simply_helpful directory if you were using it, and any existing code that depends on simply_helpful&#8217;s API should work again.</p>
<p>I was using the <a href="http://weblog.jamisbuck.org/2007/2/2/introducing-tztime">tztime</a> and <a href="http://agilewebdevelopment.com/plugins/tzinfo_timezone">tzinfo_timezone</a> plugins, which are no longer needed now that time zone support is available via Time.zone in Rails 2.2. Delete the plugins, upgrade the tzinfo gem to 0.3.12 or uninstall any older version of it, and search for TzTime instances in your code and replace any of the occurences of Time.at(some_tztime_variable) that you had been using. TzInfo is still useful in cases such as this:</p>
<pre>TZInfo::Timezone.get('UTC')</pre>
<p>But since you can now embed the time zone information in a Time instance, you don&#8217;t need TzTime objects anymore.</p>
<p>I was using a nice hack from Technoweenie, to allow me to validate forms using the familiar ActiveRecord model validations API even if those forms were not backed by a database table (sometimes the UI just doesn&#8217;t look anything like the data model, y&#8217;know?). It broke, and I was unable to find any solutions from anyone else, so I wrote my own: <a href="http://www.pervasivecode.com/blog/2008/11/29/ephemeralmodel-for-rails-222-form-validation-without-a-db-table/">EphemeralModel, for Rails 2.2.2 form validation without a DB table</a>.</p>
<p>I was using <code>ActiveRecord::Errors.default_error_messages[:invalid]</code> in a few model validators, which is now deprecated because it&#8217;s not internationalized. The new way to ask for the same string in the currently configured language is: <code>I18n.t(:invalid, :scope => 'activerecord.errors.messages')</code></p>
<p>Finally, the app wouldn&#8217;t start because it wants a <code>:secret</code> option to <code>config.action_controller.session</code> in <code>config/environment.rb</code>. I came up with something sufficiently random and now it&#8217;s fine.</p>
<p>I&#8217;d just like to make one last comment about this: having thorough automated tests is a huge time and sanity saver during this process. If you&#8217;re not close to 100% test coverage on your current Rails project, then your house is on fire and you need to address that immediately. Even as I write this in late 2008, I&#8217;m talking to prospective clients about contracting work, and some of them don&#8217;t do automated testing at all(!). Unless you&#8217;re in a mad dash for a demo that will save the company from financial collapse, having automated tests that verify that your code works should be priority #1. Upgrades can wait.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2008/11/29/things-i-had-to-fix-for-rails-222/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
