<?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</title>
	<atom:link href="http://www.pervasivecode.com/blog/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>Making Bundler 1.0.0.beta.10 install Nokogiri on Leopard with a newish libxml</title>
		<link>http://www.pervasivecode.com/blog/2010/07/25/making-bundler-1-0-0-beta-10-install-nokogiri-on-leopard-with-a-newish-libxml/</link>
		<comments>http://www.pervasivecode.com/blog/2010/07/25/making-bundler-1-0-0-beta-10-install-nokogiri-on-leopard-with-a-newish-libxml/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 05:26:08 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=219</guid>
		<description><![CDATA[Okay, now that Bundler 1.0.0.beta.10 is out, you can once again pass build-time options to gems with native extensions, such as Nokogiri. So this supercedes my older instructions for making Bundler 0.8.5 install Nokogiri on Leopard.
So now instead of making a YAML file and referring to it, pass the options like this:

bundle config build.nokogiri \
--with-xml2-include=/usr/local/include/libxml2 [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, now that Bundler 1.0.0.beta.10 is out, you can once again pass build-time options to gems with native extensions, such as Nokogiri. So this supercedes my older <a href="http://www.pervasivecode.com/blog/2010/03/17/making-bundler-0-8-5-install-nokogiri-on-leopard-with-a-newish-libxml/">instructions for making Bundler 0.8.5 install Nokogiri on Leopard</a>.</p>
<p>So now instead of making a YAML file and referring to it, pass the options like this:</p>
<pre>
bundle config build.nokogiri \
--with-xml2-include=/usr/local/include/libxml2 \
--with-xml2-lib=/usr/local/lib
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/07/25/making-bundler-1-0-0-beta-10-install-nokogiri-on-leopard-with-a-newish-libxml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fix for MacBook Pro sudden USB and Ethernet port failures</title>
		<link>http://www.pervasivecode.com/blog/2010/07/24/fix-for-macbook-pro-sudden-usb-and-ethernet-port-failures/</link>
		<comments>http://www.pervasivecode.com/blog/2010/07/24/fix-for-macbook-pro-sudden-usb-and-ethernet-port-failures/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 04:04:03 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=206</guid>
		<description><![CDATA[I own a 2.16GHz MacBook Pro, which is a little over 3 years old. Over the last year I&#8217;ve had an odd problem with it, which has gotten severe in the last few weeks. The problem was that it would suddenly disable the Ethernet port and the USB ports, disconnecting mounted disks and freezing networked [...]]]></description>
			<content:encoded><![CDATA[<p>I own a 2.16GHz MacBook Pro, which is a little over 3 years old. Over the last year I&#8217;ve had an odd problem with it, which has gotten severe in the last few weeks. The problem was that it would suddenly disable the Ethernet port and the USB ports, disconnecting mounted disks and freezing networked services. The only workaround was to reboot or sleep/wake. I finally found the cause and fixed it last week. My guess is that pretty much all MacBook Pros of similar age and design will develop this problem, so read on if you have a similar issue.<br />
<span id="more-206"></span><br />
The computer itself is a 15&#8243; 2.16GHz MacBook Pro, order number MA601LL, but I&#8217;ll bet that all of the A1150 series will have the same issue, and maybe the later models.</p>
<p>The problem would appear unpredictably, and defied my attempts to reproduce it, with one exception: Netflix Instant streaming would invariably result in a failure in less than 15 minutes of play. I tried updating the Silverlight plugin, and then simply not ever using Netflix streaming, but that didn&#8217;t help.  Eventually I found that running anything that kept the CPU near 100% utilization for a minute or so would trigger the problem. Could it be a thermal issue?</p>
<p>I use <a href="http://bjango.com/apps/istatmenus/">iStat Menus</a> so I was able to easily see that my CPU temperature was over 160&deg;F whenever this happened, and my fan speed was about 6000 RPM. I tried placing something under my laptop to increase airflow underneath it (simulating my wife&#8217;s <a href="http://www.griffintechnology.com/products/elevator">Griffin Elevator</a>), but that didn&#8217;t help. I did some searching to see if that CPU temperature and fan speed were unusual, and found the <a href="http://www.intelmactemp.com/">Intel Mac Temperature Database</a>. It seems like other folks have seen higher CPU temperatures than 160&deg;F without problems, so that probably wasn&#8217;t it.</p>
<p>I decided to dig around a bit to see if 6000 RPM was a reasonable fan speed. Apparently not; several pages I found mentioned that MacBook Pros get uncomfortably hot because the standard temperature to fan speed profile that Apple used wasn&#8217;t enough to keep the laptop cool, and so some people use <a href="http://www.eidac.de/?page_id=6">smcFanControl</a> to increase the minimum fan speed to 4000 RPM. I installed smcFanControl and found that 6000 RPM is the <i>maximum</i> fan speed it allows.</p>
<p>I wondered if maybe my laptop was getting hot, and the fans were working as hard as they could and still couldn&#8217;t keep the temperature under control?</p>
<p>Following that hypothesis led me to <a href="http://forums.macrumors.com/showpost.php?p=7616725&#038;postcount=15">this post in the &quot;Macbook overheating?&quot; thread on MacRumors</a>. Since I&#8217;ve upgraded the hard drive in every MacBook I&#8217;ve owned, I have the tools to open one up already, and the excellent <a href="http://www.ifixit.com/Guide/Repair/Installing-MacBook-Pro-15-Inch-Model-A1150-Right-Fan/499/1">iFixIt Fan Replacement Instructions</a> were almost the same as what I&#8217;d had to do for a hard disk replacement, so I decided to go ahead and open it up and take a look myself.</p>
<p>Here&#8217;s what I found:</p>
<div id="attachment_202" class="wp-caption alignnone" style="width: 310px"><a href="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/1_right_dirty.jpg"><img src="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/1_right_dirty-300x225.jpg" alt="The right fan filter is almost completely clogged." title="1_right_dirty" width="300" height="225" class="size-medium wp-image-202" /></a><p class="wp-caption-text">The right fan filter is almost completely clogged. (click to enlarge)</p></div>
<div id="attachment_203" class="wp-caption alignnone" style="width: 310px"><a href="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/2_left_dirty.jpg"><img src="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/2_left_dirty-300x225.jpg" alt="The left fan filter is also almost completely clogged." title="2_left_dirty" width="300" height="225" class="size-medium wp-image-203" /></a><p class="wp-caption-text">The left fan filter is also almost completely clogged. (click to enlarge)</p></div>
<p>Jackpot. I vacuumed the dust out. Here&#8217;s what it&#8217;s supposed to look like:</p>
<div id="attachment_204" class="wp-caption alignnone" style="width: 310px"><a href="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/3_right_clean.jpg"><img src="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/3_right_clean-300x225.jpg" alt="That&#039;s much better." title="3_right_clean" width="300" height="225" class="size-medium wp-image-204" /></a><p class="wp-caption-text">That's much better.</p></div>
<div id="attachment_205" class="wp-caption alignnone" style="width: 310px"><a href="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/4_left_clean.jpg"><img src="http://www.pervasivecode.com/blog/wp-content/uploads/2010/07/4_left_clean-300x225.jpg" alt="The left fan filter is now clean-ish." title="4_left_clean" width="300" height="225" class="size-medium wp-image-205" /></a><p class="wp-caption-text">The left fan filter is now clean-ish.</p></div>
<p>I put it back together, and the problem is gone! Cost: $0.</p>
<p>As a bonus, it runs cooler so it isn&#8217;t painful to use on my lap, and since the fans don&#8217;t have to work so hard, it&#8217;s quieter than before.</p>
<p>So if you have a flaky MacBook Pro of similar age that&#8217;s running strangely hot and your fans are running at full blast, maybe you should open it up and see what your dust situation is. Like I said, my guess is that every single MacBook Pro will experience this problem sooner or later.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/07/24/fix-for-macbook-pro-sudden-usb-and-ethernet-port-failures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Princess and the Pea, as a Cucumber Feature</title>
		<link>http://www.pervasivecode.com/blog/2010/06/01/the-princess-and-the-pea-as-a-cucumber-feature/</link>
		<comments>http://www.pervasivecode.com/blog/2010/06/01/the-princess-and-the-pea-as-a-cucumber-feature/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 20:00:41 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=197</guid>
		<description><![CDATA[Kent Beck tweeted:

User story: &#8220;As a princess I want to confirm my royalty so I get bruised after sleeping on 40 mattresses over a pea&#8221;. Just tell real stories&#8221;

That sounded so much like a Cucumber feature that I decided to write it as one:

Feature: Physical Sensitivity
  In order to confirm my royalty
  As [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://twitter.com/kentbeck/">Kent Beck</a> tweeted:</p>
<blockquote><p>
User story: &#8220;As a princess I want to confirm my royalty so I get bruised after sleeping on 40 mattresses over a pea&#8221;. Just tell real stories&#8221;
</p></blockquote>
<p>That sounded so much like a <a href="http://cukes.info/">Cucumber</a> feature that I decided to write it as one:</p>
<pre>
Feature: Physical Sensitivity
  In order to confirm my royalty
  As a princess
  I want to be very delicate

  Scenario: 40 mattresses on a pea
  Given there is a pea on the bed
  And there is a stack of 20 mattresses on the pea
  And there is a stack of 20 featherbeds on the mattresses
  When I try to sleep on top of the stack of featherbeds
  Then I should not be able to sleep
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/06/01/the-princess-and-the-pea-as-a-cucumber-feature/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unix tip: kill -STOP and kill -CONT</title>
		<link>http://www.pervasivecode.com/blog/2010/04/03/unix-tip-kill-stop-and-kill-cont/</link>
		<comments>http://www.pervasivecode.com/blog/2010/04/03/unix-tip-kill-stop-and-kill-cont/#comments</comments>
		<pubDate>Sun, 04 Apr 2010 01:31:44 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=194</guid>
		<description><![CDATA[Pretty much every Unix user knows about the kill command, and most know about &#8216;kill -KILL&#8217; aka &#8216;kill -9&#8242;.
But do you know about kill -STOP and kill -CONT?

I&#8217;m not sure of the exact mechanism (kernel vs. user process) but everything I&#8217;ve used it on on a Mac OS X machine has responded to it in [...]]]></description>
			<content:encoded><![CDATA[<p>Pretty much every Unix user knows about the kill command, and most know about &#8216;kill -KILL&#8217; aka &#8216;kill -9&#8242;.</p>
<p>But do you know about kill -STOP and kill -CONT?<br />
<span id="more-194"></span><br />
I&#8217;m not sure of the exact mechanism (kernel vs. user process) but everything I&#8217;ve used it on on a Mac OS X machine has responded to it in the same way. So you may find a process that doesn&#8217;t do this, but I haven&#8217;t found one.</p>
<p>Basically <code>kill -STOP 1234</code> will pause the process with pid 1234, and <code>kill -CONT 1234</code> will resume it. It&#8217;s as if you can sleep individual applications instead of your entire computer.</p>
<p>It&#8217;s simple, but you can probably imagine why this would be useful. Want to keep Firefox with 45 tabs open, but you&#8217;re not using it for a while and you want to save battery life? Pause it. Pretty much anything like &#8220;I don&#8217;t want to quit and then re-launch this but I wish it wasn&#8217;t using a bunch of CPU time while it idles&#8221; is a good candidate.</p>
<p>Remember that this means your app my time out when it is resumed, as if you had slept your laptop. So network connections it had open when you paused it may be broken when you resume it. So pausing Terminal.app with a bunch of open ssh connections to remote servers isn&#8217;t going to work too well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/04/03/unix-tip-kill-stop-and-kill-cont/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>Using RVM to install REE 1.8.7-2009.10</title>
		<link>http://www.pervasivecode.com/blog/2010/03/16/using-rvm-to-install-ree-1-8-7-2009-10/</link>
		<comments>http://www.pervasivecode.com/blog/2010/03/16/using-rvm-to-install-ree-1-8-7-2009-10/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 01:48:53 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=160</guid>
		<description><![CDATA[I&#8217;m trying out Ruby Version Manager this week, and my first impression is that this is some cool technology. But I wasn&#8217;t able to figure out how to get it to install an older version of REE to get around this bug (the &#8220;Marshal.load reentered at marshal_load&#8221; issue).
Igor P&#8217;s solution is correct (just install REE [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m trying out <a href="http://rvm.beginrescueend.com/">Ruby Version Manager</a> this week, and my first impression is that this is some cool technology. But I wasn&#8217;t able to figure out how to get it to install an older version of REE to get around <a href="http://groups.google.com/group/emm-ruby/browse_thread/thread/ba3ef0a931618052">this bug</a> (the &#8220;Marshal.load reentered at marshal_load&#8221; issue).</p>
<p>Igor P&#8217;s solution is correct (just install REE 1.8.7-2009.10), but it took a little fiddling to figure out how to get RVM to use the older version of REE. Here&#8217;s how to do it:</p>
<pre>
cd ~/.rvm/archives
wget -q http://rubyforge.org/frs/download.php/66162/ruby-enterprise-1.8.7-2009.10.tar.gz
rvm install ree-1.8.7-2009.10
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/03/16/using-rvm-to-install-ree-1-8-7-2009-10/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Karmic on Xen with Bad /etc/fstab = PAIN</title>
		<link>http://www.pervasivecode.com/blog/2010/02/07/karmic-on-xen-with-bad-etcfstab-pain/</link>
		<comments>http://www.pervasivecode.com/blog/2010/02/07/karmic-on-xen-with-bad-etcfstab-pain/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 00:32:20 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=156</guid>
		<description><![CDATA[Argh! I spent about 5 hours yesterday troubleshooting a failed Ubuntu Jaunty -> Karmic (9.04->9.10) upgrade. It worked fine until I rebooted and then failed to boot. Here&#8217;s how I fixed it.

It failed to boot, saying this:

One or more mounts listed in /etc/fstab cannot yet be mounted
/ : waiting for /dev/xvda1
/tmp : waiting for (null)
/swap [...]]]></description>
			<content:encoded><![CDATA[<p>Argh! I spent about 5 hours yesterday troubleshooting a failed Ubuntu Jaunty -> Karmic (9.04->9.10) upgrade. It worked fine until I rebooted and then failed to boot. Here&#8217;s how I fixed it.<br />
<span id="more-156"></span><br />
It failed to boot, saying this:<br />
<code><br />
One or more mounts listed in /etc/fstab cannot yet be mounted<br />
/ : waiting for /dev/xvda1<br />
/tmp : waiting for (null)<br />
/swap : waiting for /dev/xvda9<br />
</code></p>
<p>I tried a lot of stuff and finally solved it. My solution is on the Ubuntu Forum, here: <a href="http://ubuntuforums.org/showpost.php?p=8789500&#038;postcount=37">One or more of the mounts listed in /etc/fstab/ cannot yet be mounted (Karmic)</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/02/07/karmic-on-xen-with-bad-etcfstab-pain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu 9.10 (Jaunty Jackalope) upgrade notes</title>
		<link>http://www.pervasivecode.com/blog/2010/02/06/ubuntu-910-jaunty-jackalope-upgrade-notes/</link>
		<comments>http://www.pervasivecode.com/blog/2010/02/06/ubuntu-910-jaunty-jackalope-upgrade-notes/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 04:24:57 +0000</pubDate>
		<dc:creator>Jamie Flournoy</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[servers]]></category>

		<guid isPermaLink="false">http://www.pervasivecode.com/blog/?p=154</guid>
		<description><![CDATA[Once again Ubuntu Linux proves itself to be easy to upgrade. Going from 9.04 to 9.10 (one release newer, since their numbering is bsaed on dates) was easy, but included the standard sprinkling of manual re-customization that I&#8217;ve come to expect from Debian based systems.

I did the Network Upgrade for Servers.
I had to re-customize these [...]]]></description>
			<content:encoded><![CDATA[<p>Once again Ubuntu Linux proves itself to be easy to upgrade. Going from 9.04 to 9.10 (one release newer, since their numbering is bsaed on dates) was easy, but included the standard sprinkling of manual re-customization that I&#8217;ve come to expect from Debian based systems.<br />
<span id="more-154"></span><br />
I did the <a href="https://help.ubuntu.com/community/KarmicUpgrades#Network%20Upgrade%20for%20Ubuntu%20Servers%20%28Recommended%29">Network Upgrade for Servers</a>.</p>
<p>I had to re-customize these files since I&#8217;m not running with 100% default configuration:</p>
<p>/etc/monit/monit<br />
/etc/monit/monitrc<br />
/etc/dovecot/dovecot.conf<br />
/etc/apache2/apache2.conf<br />
/etc/php/apache2/php.ini</p>
<p>I basically did a manual diff side by side in Emacs and copied my changes over into the new config files. Reboot, no problems. Nice.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pervasivecode.com/blog/2010/02/06/ubuntu-910-jaunty-jackalope-upgrade-notes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
