tag:blogger.com,1999:blog-22652558557142527232024-02-19T07:25:30.981-08:00NathenNathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-2265255855714252723.post-88228378375225565312011-12-29T07:32:00.000-08:002011-12-29T07:33:35.927-08:00Blog movedI've moved my blog to one built using <a href="http://octopress.org/">Octopress</a>. Please head over to <a href="http://nathenharvey.com">http://nathenharvey.com</a> to read my blog.Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-85453346826295999642011-12-13T19:53:00.000-08:002011-12-29T06:42:16.088-08:00Agenda Tips for a Tech User Group<meta http-equiv="REFRESH" content="0;url=http://nathenharvey.com/blog/2011/12/13/agenda-tips-for-a-tech-user-group/"></HEAD><br />Redirecting to <a href="http://nathenharvey.com/blog/2011/12/13/agenda-tips-for-a-tech-user-group/">http://nathenharvey.com</a>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-38836180022022748012011-12-13T19:24:00.000-08:002011-12-29T06:29:12.476-08:00Tips for Hosting a Tech User Group<meta http-equiv="REFRESH" content="0;url=http://nathenharvey.com/blog/2011/12/13/tips-for-hosting-a-tech-user-group/"></HEAD><br />Redirecting to <a href="http://nathenharvey.com/blog/2011/12/13/tips-for-hosting-a-tech-user-group/">http://nathenharvey.com</a>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com2tag:blogger.com,1999:blog-2265255855714252723.post-43626865405445182302011-11-21T04:48:00.000-08:002011-12-29T06:34:18.974-08:00Brine your turkey!<meta http-equiv="REFRESH" content="0;url=http://nathenharvey.com/blog/2011/11/21/brine-your-turkey/"></HEAD><br />Redirecting to <a href="http://nathenharvey.com/blog/2011/11/21/brine-your-turkey/">http://nathenharvey.com</a>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-51618606746639662972011-11-21T03:57:00.000-08:002011-12-29T06:33:37.838-08:00I'm Speaking at MongoSV<meta http-equiv="REFRESH" content="0;url=http://nathenharvey.com/blog/2011/11/21/im-speaking-at-mongosv/"></HEAD><br />Redirecting to <a href="http://nathenharvey.com/blog/2011/11/21/im-speaking-at-mongosv/">http://nathenharvey.com</a>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com3tag:blogger.com,1999:blog-2265255855714252723.post-3619266244156766742011-11-21T03:29:00.001-08:002011-12-29T06:32:56.792-08:00Why we chose Chef over Puppet at CustomInk<meta http-equiv="REFRESH" content="0;url=http://nathenharvey.com/blog/2011/11/21/why-we-chose-chef-over-puppet-at-customink/"></HEAD><br />Redirecting to <a href="http://nathenharvey.com/blog/2011/11/21/why-we-chose-chef-over-puppet-at-customink/">http://nathenharvey.com</a>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com5tag:blogger.com,1999:blog-2265255855714252723.post-55437626486807078192010-12-27T19:25:00.000-08:002011-12-29T06:32:22.884-08:00Vagrant and VBoxManage import<meta http-equiv="REFRESH" content="0;url=http://nathenharvey.com/blog/2010/12/27/vagrant-and-vboxmanage-import/"></HEAD><br />Redirecting to <a href="http://nathenharvey.com/blog/2010/12/27/vagrant-and-vboxmanage-import//">http://nathenharvey.com</a>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-23362201000373928292010-12-02T21:11:00.000-08:002011-12-29T06:31:46.142-08:00Citizen Cope Concert<meta http-equiv="REFRESH" content="0;url=http://nathenharvey.com/blog/2010/12/02/citizen-cope-concert/"></HEAD><br />Redirecting to <a href="http://nathenharvey.com/blog/2010/12/02/citizen-cope-concert/">http://nathenharvey.com</a>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-34836953782029800332010-07-16T09:00:00.000-07:002011-12-29T06:31:14.228-08:00Testing mod_rewrite and apache redirects<meta http-equiv="REFRESH" content="0;url=http://nathenharvey.com/blog/2010/07/16/testing-mod-rewrite-and-apache-redirects/"></HEAD><br />Redirecting to <a href="http://nathenharvey.com/blog/2010/07/16/testing-mod-rewrite-and-apache-redirects/">http://nathenharvey.com</a>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-29470256840004416142010-06-11T09:25:00.000-07:002011-12-29T06:30:33.050-08:00Passenger and PHP<meta http-equiv="REFRESH" content="0;url=http://nathenharvey.com/blog/2010/06/11/passenger-and-php/"></HEAD><br />Redirecting to <a href="http://nathenharvey.com/blog/2010/06/11/passenger-and-php/">http://nathenharvey.com</a>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-86291423237547658992009-11-28T06:22:00.000-08:002009-11-28T06:28:56.411-08:00Cooking the TurkeyWhen it's done in the brine, take it out, rinse it off and pat it dry with a paper towel.<br /><br /><br />Here it is, ready to go into the roasting pan.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8d02MCapIi0fWLnaVm16IT48gCNBGHQsNQZoLlukNSnd8Yob05OJCBpqAjHuY-OV1peqYeiV54vRv37U04RnUC3t1LeYz_NhS38MzyfNwCKsVHm5zN0AwUKIizBSkrhM3fVmrVtMNOX8/s1600/IMG_5004.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8d02MCapIi0fWLnaVm16IT48gCNBGHQsNQZoLlukNSnd8Yob05OJCBpqAjHuY-OV1peqYeiV54vRv37U04RnUC3t1LeYz_NhS38MzyfNwCKsVHm5zN0AwUKIizBSkrhM3fVmrVtMNOX8/s320/IMG_5004.JPG" alt="" id="BLOGGER_PHOTO_ID_5409160119380853826" border="0" /></a><br /><br />I pulled it out of the oven at about 155 degrees and let it carryover cook, tented with foil, to 165.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIc0r56VUZh90nFsaDXWnq20TDn0XgQEOq6oWo3G_1-zZguvOdU-nQIbXJv1gvDBbJsJhWpg4FdCEuxpPlOxlJFt7Ns0VCNGY7It4Q9ItYz7v0_urjFWJ5oyAKkYhW1VKBA8KZIbCkfWo/s1600/IMG_5005.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIc0r56VUZh90nFsaDXWnq20TDn0XgQEOq6oWo3G_1-zZguvOdU-nQIbXJv1gvDBbJsJhWpg4FdCEuxpPlOxlJFt7Ns0VCNGY7It4Q9ItYz7v0_urjFWJ5oyAKkYhW1VKBA8KZIbCkfWo/s320/IMG_5005.JPG" alt="" id="BLOGGER_PHOTO_ID_5409160542565948018" border="0" /></a><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYT91fQ0Wx0rbxWNypm9qFJNdnpts78VZAOjeMwld9U5OiREFDuqJz6xVfvN-zTjXNh7yvkSjGf6bVowc_LOvvIUNrJbhtqdy4EKJEgpJxkRXuip6cjISiF2_CZpEVoasZsoCc-ezg-wc/s1600/IMG_5006.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYT91fQ0Wx0rbxWNypm9qFJNdnpts78VZAOjeMwld9U5OiREFDuqJz6xVfvN-zTjXNh7yvkSjGf6bVowc_LOvvIUNrJbhtqdy4EKJEgpJxkRXuip6cjISiF2_CZpEVoasZsoCc-ezg-wc/s320/IMG_5006.JPG" alt="" id="BLOGGER_PHOTO_ID_5409160663901881906" border="0" /></a><br /><br />The finished product. Note the skin looks a little "cajun" in some areas but, trust me, it was delicious!<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgs9PuZG6TBqIFkqrdIR8uSq_wJw9_GvTm4rwXN_0v0EWdcV_VY2di5Q2EBfd1MynX15GYGtAU47NXuG9EkmMexxd3mDGgNJxNP7XCczFjiBwgTn3eONlHHYGrKV8GpgXE3jdRlbN_qCNc/s1600/IMG_5007.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgs9PuZG6TBqIFkqrdIR8uSq_wJw9_GvTm4rwXN_0v0EWdcV_VY2di5Q2EBfd1MynX15GYGtAU47NXuG9EkmMexxd3mDGgNJxNP7XCczFjiBwgTn3eONlHHYGrKV8GpgXE3jdRlbN_qCNc/s320/IMG_5007.JPG" alt="" id="BLOGGER_PHOTO_ID_5409160929641727986" border="0" /></a><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju0nhAseVJgEJCprBpc5Ko-GSVrab0XYb52MZyd-Ztjm49CX-Wpb90ysprZx_Dp9bN5pSm4nWVY5LAtgjHtlMsSzXn1zokbGy67QOxaS1xzHXCumyzjNuwy3N-xYRdV6Edx0kJ2ZQ4bSI/s1600/IMG_5008.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju0nhAseVJgEJCprBpc5Ko-GSVrab0XYb52MZyd-Ztjm49CX-Wpb90ysprZx_Dp9bN5pSm4nWVY5LAtgjHtlMsSzXn1zokbGy67QOxaS1xzHXCumyzjNuwy3N-xYRdV6Edx0kJ2ZQ4bSI/s320/IMG_5008.JPG" alt="" id="BLOGGER_PHOTO_ID_5409161176193105250" border="0" /></a><br />I hope you all had a great Thanksgiving!Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-14550740567681834862009-11-25T12:30:00.001-08:002009-11-26T04:37:50.035-08:00Preparing the Turkey<span style="font-family:trebuchet ms;">The brine is ready, it's time to add the turkey.</span><br /><p><br /><span style="font-family:trebuchet ms;">A quick trip over to </span><a style="font-family: trebuchet ms;" href="http://www.maplelawn.com/">Maple Lawn Farms</a><span style="font-family:trebuchet ms;"> to pick-up a bird. This 23.5 pounder was walking around this morning! It doesn't get much fresher than that.</span><br /></p><br /><p><br /><a style="font-family: trebuchet ms;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi-aUTgsdWi5swNhaFhPYawa_tmZznMnoDTM9fVa0wl_iDSDqFp5tiH2OAaTgT8_xfZ3lAMAruQDxIrYADbXJvBKc76yDOEPi74a2lrurPnYPppgd1eHOY5rIjFyKtUzTHi0tQAwXuhR4/s1600/onthefarm.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 267px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi-aUTgsdWi5swNhaFhPYawa_tmZznMnoDTM9fVa0wl_iDSDqFp5tiH2OAaTgT8_xfZ3lAMAruQDxIrYADbXJvBKc76yDOEPi74a2lrurPnYPppgd1eHOY5rIjFyKtUzTHi0tQAwXuhR4/s320/onthefarm.jpg" alt="" id="BLOGGER_PHOTO_ID_5408142027809292482" border="0" /></a><br /><span style="font-family:trebuchet ms;">They wrapped the turkey in butcher paper. Open it up, stuff it with orange quarters, and get it into the brine. It's important to keep it COLD so I'll put the brine into a cooler filled with plenty of ice. Need to watch it for the next 24 hours or so to be sure it stays cold and add ice as necessary. Once in the brine, I'll rotate the bird once or twice. In the past, I've used large plastic bags to hold the brine and turkey. This year, I'm trying a bucket and so far I'm very pleased. Much easier to manage, cleaner, and I don't have to worry about it splitting open and spilling the brine all over my kitchen when I move it around.</span><br /></p><br /><p><br /><a style="font-family: trebuchet ms;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsVAPYM53i63R29OlFCMjoesHNaGx-icmSGZ06vCkve-ICEYT9Vg1nHkDxHuUR8D6H8EuC83EToIeqrWMO7tXAt7WcZ26oyUE2AUXEnPV0S1mdObY4uXRCBfMN1N0fDo2wgD3sZ4o0FVE/s1600/kitchen.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 285px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsVAPYM53i63R29OlFCMjoesHNaGx-icmSGZ06vCkve-ICEYT9Vg1nHkDxHuUR8D6H8EuC83EToIeqrWMO7tXAt7WcZ26oyUE2AUXEnPV0S1mdObY4uXRCBfMN1N0fDo2wgD3sZ4o0FVE/s320/kitchen.jpg" alt="" id="BLOGGER_PHOTO_ID_5408142991028402850" border="0" /></a><br /></p><br /><p><br /><span style="font-family:trebuchet ms;">Here's what will happen once I'm ready to cook the turkey:</span><br /></p><br /><ol style="font-family: trebuchet ms;"><li>Preheat oven to 500 degrees</li><li>Remove the turkey from the brine, rinse it, and pat dry with paper towels</li><li>Line roasting pan with carrots, celery, and onions. Add chicken broth.<br /></li><li>Fill the turkey's cavity with garlic, sage, thyme, parsley, and onion</li><li>Put turkey in the pan, breast side down for now</li><li>Brush turkey with butter, sprinkle with salt and pepper</li><li>Bake at 500 for 30 minutes</li></ol><span style="font-family:trebuchet ms;">After 30 minutes at 500 degrees:</span><br /><br /><ol style="font-family: trebuchet ms;"><li>Reduce oven to 350 degrees</li><li>Flip the turkey over, breast side up</li><li>Cook to an internal temperature of about 155</li><li>Don't worry, it'll get to 165 as it rests. This should also prevent you from carving it too soon.<br /></li></ol><br /><p><span style="font-family:trebuchet ms;">As it cooks, I'll be sure to watch the skin so that it doesn't get too dark. If I feel that it will, I'll tent the turkey with some aluminum foil. One of the most important pieces of the cooking process is to use a </span><a style="font-family: trebuchet ms;" href="http://www.williams-sonoma.com/products/sku6700488/?pkey=x%7C4%7C1%7C%7C4%7Cmeat%20thermometer%7C%7C0&cm_src=SCH">leave-in thermometer</a><span style="font-family:trebuchet ms;">. This will let you keep the oven closed which keeps the heat in. There's no need to baste the turkey as it cooks. My motto: "always brine, never open the oven."</span><br /></p><br /><p><br /><span style="font-family:trebuchet ms;">As for carving? I'm planning on trying something new this year but we'll ask Alton Brown for some tips on how. </span><a style="font-family: trebuchet ms;" href="http://www.seriouseats.com/2009/11/video-alton-brown-on-how-to-carve-a-turkey.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+seriouseatsfeaturesvideos+%28Serious+Eats%29">Watch this video to see how</a><span style="font-family:trebuchet ms;">.</span><br /></p><br /><p><br /><span style="font-family:trebuchet ms;">With the turkey, we'll have a bunch of the usual sides, and plenty of beverage options. Personally, I'll be having a </span><a style="font-family: trebuchet ms;" href="http://www.toadhollow.com/available.asp#2">Toad Hollow Chardonnay</a><span style="font-family:trebuchet ms;">.</span><br /></p><br /><p><br /><span style="font-family:trebuchet ms;">I hope you and your family have a happy and safe Thanksgiving!</span><br /><b style="font-family: trebuchet ms;"><a name="2"><b></b></a></b></p>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com1tag:blogger.com,1999:blog-2265255855714252723.post-36177514047355596232009-11-23T18:19:00.000-08:002009-11-23T18:33:58.580-08:00Turkey Time<span style="font-family: trebuchet ms;">It's not Thanksgiving yet but to properly prepare for my turkey it's time to start mixing up the brine. </span><br /><br /><span style="font-family: trebuchet ms;">Here's my grocery list:</span><br /><ul style="font-family: trebuchet ms;"><li>apple cider</li><li>kosher salt</li><li>sugar</li><li>fresh ginger</li><li>black pepper</li><li>all spice</li><li>cloves</li><li>bay leaves</li></ul><br /><span style="font-family: trebuchet ms;">While at the store, I noticed that they're selling Egg Nog. Feels a little early for nog but I've got some Jameson's at home so why not?</span><br /><br /><br /><br /><span style="font-size:130%;"><span style="font-family: trebuchet ms; font-weight: bold;">Start the mixing:</span></span><br /><br /><br /><br /><span style="font-family: trebuchet ms;"><span style="font-weight: bold;">Step 1</span> - Jameson's and Egg Nog in the shaker. Serve over ice with a bit of nutmeg. Looks like my wife already has a cup of tea but the nog shouldn't be a hard sell.</span><br /><br /><br /><br /><span style="font-family: trebuchet ms;"><span style="font-weight: bold;">Step 2</span> - Get all the other ingredients going on the stove long enough to let the sugar and salt dissolve and make the house smell like Thanksgiving.</span><br /><br /><br /><br /><span style="font-family: trebuchet ms;">The brine will have plenty of time to cool. Picking up the turkey from </span><a style="font-family: trebuchet ms;" href="http://www.maplelawn.com/">Maple Lawn Farms </a><span style="font-family: trebuchet ms;">tomorrow.</span>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com1tag:blogger.com,1999:blog-2265255855714252723.post-10353196294068844952009-09-14T07:02:00.000-07:002009-09-14T07:24:49.001-07:00Just the domain<span style="font-family:trebuchet ms;">I've done this a couple of times before but found myself having to dig through docs to remember how so thought I'd put up a post for future reference.</span><br /><br /><span style="font-family:trebuchet ms;">I wanted to group some users by their email domain for a query I was running in my PostgreSQL database. I have a users table with an email column. Here's a query I ran:</span><br /><br /><pre><br />select count(*) as users, <br />substring(email from (position('@' in email))+1) as "domain"<br />from users<br />group by domain<br />order by users desc<br />limit 10;<br /><br /><br /> users | domain <br />-------+---------------<br /> XXXXX | yahoo.com<br /> XXXXX | gmail.com<br /> XXXXX | hotmail.com<br /> XXXXX | aol.com<br /> XXXXX | comcast.net<br /> XXXXX | msn.com<br /> XXXXX | sbcglobal.net<br /> XXXXX | live.com<br /> XXXXX | verizon.net<br /> XXXXX | ymail.com<br /></pre><br /><br /><span style="font-family:trebuchet ms;">This allows me to select the email domain from the email column. Pretty handy.</span>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-59902446357844336402009-06-24T10:43:00.000-07:002009-06-24T10:52:11.883-07:00TweetDeck - How to follow multiple accounts<span style="font-family: verdana;font-family:verdana;" >With the latest version of <a href="http://tweetdeck.com/">TweetDeck</a>, you can now easily follow many accounts at one time. Here's a quick step-by-step to show you how.</span> <ul style="font-family: verdana;"><li>Click the Add more acccounts link (or Accounts tab in the Settings screen)</li></ul><a style="font-family: verdana;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSUbn52WvKoUAo14XMwPO9dWlZDRDTcI3VBuZthEeNXUdKK9nSqlIlep8bcH_63_Bsqxkd-CuPC7cGjPdxTd7phs39SLJCYLCfVYjnJQzY_zLVcYM8A6TDADU5vhhPcx2lkaV9gBJ9sg4/s1600-h/add_more_accounts.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 295px; height: 155px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSUbn52WvKoUAo14XMwPO9dWlZDRDTcI3VBuZthEeNXUdKK9nSqlIlep8bcH_63_Bsqxkd-CuPC7cGjPdxTd7phs39SLJCYLCfVYjnJQzY_zLVcYM8A6TDADU5vhhPcx2lkaV9gBJ9sg4/s320/add_more_accounts.jpg" alt="" id="BLOGGER_PHOTO_ID_5350952091097119426" border="0" /></a><ul style="font-family: verdana;"><li>Enter the account credentials (Username and Password) then add the account and save.</li></ul><a style="font-family: verdana;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhroPlCOhwvJ1Hz6yAsNHrbx4YNJJnwCRx2f_PO5e4v5aHoUSSssCwqvI622JNrk15Pjz_IMj3RdBIKzJQFan4slJSmWnhozt9RZ0tYX6pxc8NmAtCYUsx_YJgvuqCB7JDajmLea6_vjLw/s1600-h/add_the_account.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 210px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhroPlCOhwvJ1Hz6yAsNHrbx4YNJJnwCRx2f_PO5e4v5aHoUSSssCwqvI622JNrk15Pjz_IMj3RdBIKzJQFan4slJSmWnhozt9RZ0tYX6pxc8NmAtCYUsx_YJgvuqCB7JDajmLea6_vjLw/s320/add_the_account.jpg" alt="" id="BLOGGER_PHOTO_ID_5350952213502798386" border="0" /></a><br /><br /><ul style="font-family: verdana;"><li>Click the "All Friends" column to add a new column.</li></ul><a style="font-family: verdana;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxoAMM6F3CtBiR_lCtg1LgR1c2adeBdO5UDnQPc0SA9t3u7rJkqiuy-G4D4jPvVSLIH7GgGIzGC6iKJZfknNqL8Uj-lG2ZwxmyUHwCH2EcUs9Soc3BmlfwbWwBrAh0FUBlgAwyeKopfm8/s1600-h/addcolumn.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 208px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxoAMM6F3CtBiR_lCtg1LgR1c2adeBdO5UDnQPc0SA9t3u7rJkqiuy-G4D4jPvVSLIH7GgGIzGC6iKJZfknNqL8Uj-lG2ZwxmyUHwCH2EcUs9Soc3BmlfwbWwBrAh0FUBlgAwyeKopfm8/s320/addcolumn.jpg" alt="" id="BLOGGER_PHOTO_ID_5350952299041835586" border="0" /></a><ul style="font-family: verdana;"><li>Using the drop-down arrow, select the account you want to add the column for.</li></ul><a style="font-family: verdana;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcZGNaAia4uy7PSfyRw8jLLM8vRZV-vKP82sE4iKa0Pmi1woXc9jYs3g6Uuj6Z55KeD4TDVvz45bMg9sb9TnciQKp5SpgtohrHJwhg6aRNVc5T-xsyxhVqg2u1rzPKDIGiQDwXjFu20rQ/s1600-h/select+account.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 197px; height: 163px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcZGNaAia4uy7PSfyRw8jLLM8vRZV-vKP82sE4iKa0Pmi1woXc9jYs3g6Uuj6Z55KeD4TDVvz45bMg9sb9TnciQKp5SpgtohrHJwhg6aRNVc5T-xsyxhVqg2u1rzPKDIGiQDwXjFu20rQ/s320/select+account.jpg" alt="" id="BLOGGER_PHOTO_ID_5350952495261955570" border="0" /></a><br /><span style="font-family: verdana;">One thing to watch out for, when posting a tweet pay special attention to which account(s) the tweet will be "From". You might not want to post as multiple personalities. Just click each account to toggle it on / off.</span><br /><br /><a style="font-family: verdana;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIVgbFfKGfVFKLfwk8boW5qV6PsmAEy338ACNwxHgv0gtx8z6iqrca3NNkq_JE_xRmIlWL0wrtfR4VjF7QLjMgKRIBC1wfsSGUFY6kW4mz5NcwzJHgA4sIXkHxth3WEazzRYLg6QkhZqs/s1600-h/warning.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 64px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIVgbFfKGfVFKLfwk8boW5qV6PsmAEy338ACNwxHgv0gtx8z6iqrca3NNkq_JE_xRmIlWL0wrtfR4VjF7QLjMgKRIBC1wfsSGUFY6kW4mz5NcwzJHgA4sIXkHxth3WEazzRYLg6QkhZqs/s320/warning.jpg" alt="" id="BLOGGER_PHOTO_ID_5350953258837827138" border="0" /></a>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-42854512936753410602009-04-07T06:20:00.000-07:002009-04-07T06:53:47.238-07:00SVN to git and cruisecontrol.rb<span class="Apple-style-span" style="font-family:'trebuchet ms';">We're finally moving from svn to git. Yesterday, I worked on upgrading our <a href="http://cruisecontrolrb.thoughtworks.com/">cruisecontrol.rb</a> to monitor our git repository. Previously, we were on svn and using cruisecontrolrb-1.2.1 so it was time to upgrade CruiseControl and migrate to git in one fell swoop.</span><div><span class="Apple-style-span" style="font-family:'trebuchet ms';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'trebuchet ms';">Our team uses <a href="http://www.unfuddle.com/">Unfuddle</a> so the first step was to work with them on completing the svn git clone.</span></div><div><span class="Apple-style-span" style="font-family:'trebuchet ms';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'trebuchet ms';">Our cruisecontrol set-up includes an apache web server in front of the cruisecontrol.rb rails application with integration to our <a href="http://www.campfirenow.com/"><span class="Apple-style-span" style="font-family:georgia;">Campfire</span></a> room via a plugin.</span></div><div><span class="Apple-style-span" style="font-family:'trebuchet ms';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'trebuchet ms';">Here are</span><span class="Apple-style-span" style="font-family:'trebuchet ms';"> the steps I followed:</span></div><div><span class="Apple-style-span" style="font-family:'trebuchet ms';"><br /></span></div><div><ol><li><span class="Apple-style-span" style="font-family:'trebuchet ms';">Set-up a user that has read-only access to our git repository - The steps I followed here were specific to Unfuddle and included putting the public key into the Unfuddle user's personal settings.</span></li><li><span class="Apple-style-span" style="font-family:'trebuchet ms';">Build Cruisecontrol.rb</span><span class="Apple-style-span" style="font-family:'trebuchet ms';"> - </span><span class="Apple-style-span" style="font-family:'courier new';">git clone \ git://github.com/thoughtworks/cruisecontrol.rb.git</span><br /></li><li><span class="Apple-style-span" style="font-family:'trebuchet ms';">Copy the campfire plugin from </span><span class="Apple-style-span" style="font-family:'courier new';">OLD_CRUISE_ROOT/builder_plugins/installed/campfire_notifiter.rb</span><span class="Apple-style-span" style="font-family:'trebuchet ms';"> to </span><span class="Apple-style-span" style="font-family:'courier new';">NEW_CRUISE_ROOT/lib/builder_plugins</span></li><li><span class="Apple-style-span" style="font-family:'trebuchet ms';">Copy .yml files from </span><span class="Apple-style-span" style="font-family:'courier new';">OLD_CRUISE_ROOT/config</span><span class="Apple-style-span" style="font-family:'trebuchet ms';"> to </span><span class="Apple-style-span" style="font-family:'courier new';">NEW_CRUISE_ROOT/config</span></li><li><span class="Apple-style-span" style="font-family:'trebuchet ms';">Update my front-end apache server to point to the new cruise installation</span></li><li><span class="Apple-style-span" style="font-family:'trebuchet ms';">remove the .htaccess file from </span><span class="Apple-style-span" style="font-family:'courier new';">NEW_CRUISE_ROOT/public/.htaccess</span></li></ol><div><span class="Apple-style-span" style="font-family:'trebuchet ms';">With all the configuration complete, I'm now ready to add projects. In the svn days, we'd always monitor trunk and the branch currently running in production. Here's how to add the same using git:</span></div><div><span class="Apple-style-span" style="font-family:'trebuchet ms';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';">./cruise add PROJECT_NAME --source-control git \</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">--repository git@our.host:repo/name.git</span></div><div><span class="Apple-style-span" style="font-family:'trebuchet ms';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';">./cruise add PROJECT_NAME --source-control git \</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">--repository git@our.host:repo/name.git --branch BRANCH_NAME</span><br /></div><div><span class="Apple-style-span" style="font-family:'trebuchet ms';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'trebuchet ms';"><br /></span></div></div>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com1tag:blogger.com,1999:blog-2265255855714252723.post-11526341073478495292009-03-13T18:42:00.000-07:002009-03-13T18:44:58.399-07:00St. Baldrick's<span class="Apple-style-span" style="font-family: 'trebuchet ms';">I'm shaving my head on Sunday for charity!</span><div><span class="Apple-style-span" style="font-family: 'trebuchet ms';"><br /></span></div><div><span class="Apple-style-span" style="font-family: 'trebuchet ms';">Check it out - </span><a href="http://tinyurl.com/cor2ju"><span class="Apple-style-span" style="font-family: 'trebuchet ms';">http://tinyurl.com/cor2ju</span></a></div>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-34917481983457520542008-10-31T03:20:00.000-07:002009-07-28T06:35:13.160-07:00SlideshareHave you heard of Slideshare? "SlideShare is the world's largest community for sharing presentations."<div><br /></div><div>Interesting idea. Upload and share your powerpoint presentations. Get your very own Slidespace. Mine's at http://www.slideshare.net/nathenharvey. <br /><br />Here's a one-slide presentation I put together to test out the service. Are you using the service? What's your Slidespace?<br /><br /><div style="width:425px;text-align:left" id="__ss_708497"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/nathenharvey/get-real-get-a-visualcv-presentation?type=powerpoint" title="Get Real Get A Visualcv">Get Real Get A Visualcv</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?rel=0&doc=getrealgetavisualcv-1225448151997093-9&stripped_title=get-real-get-a-visualcv-presentation"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://static.slideshare.net/swf/ssplayer2.swf?rel=0&doc=getrealgetavisualcv-1225448151997093-9&stripped_title=get-real-get-a-visualcv-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View SlideShare <a style="text-decoration:underline;" href="http://www.slideshare.net/nathenharvey/get-real-get-a-visualcv-presentation?type=powerpoint" title="View Get Real Get A Visualcv on SlideShare">presentation</a> or <a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own. (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/myspace">myspace</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/facebook">facebook</a>)</div><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><br /></div><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><br /></div></div></div>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-18995415978482495802008-10-09T08:43:00.001-07:002008-10-09T08:47:48.452-07:00Fun with Gmail addresses<span class="Apple-style-span" style="font-family: 'trebuchet ms';">You may already know this (I just found out myself) but Gmail supports plus-addressing.</span><div><span class="Apple-style-span" style="font-family: 'trebuchet ms';"><br /></span></div><div><span class="Apple-style-span" style="font-family: 'trebuchet ms';">In other words, you can send an email to yourusername+anystring@gmail.com and it'll be delivered to yourusername@gmail.com.</span></div><div><span class="Apple-style-span" style="font-family: 'trebuchet ms';"><br /></span></div><div><span class="Apple-style-span" style="font-family: 'trebuchet ms';">As it turns out, gmail also ignores any periods in the username so your.username@gmail.com will go to yourusername@gmail.com as will y.ou.ruserna.me@gmail.com.</span></div><div><span class="Apple-style-span" style="font-family: 'trebuchet ms';"><br /></span></div><div><span class="Apple-style-span" style="font-family: 'trebuchet ms';">This is a pretty handy!</span></div><div><br /></div><div><br /></div>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-22079775015226920892008-07-31T05:10:00.000-07:002008-07-31T05:20:41.769-07:00Restore the history of a file in subversion<span style="font-family:trebuchet ms;">I have a file (some_controller.rb) currently at revision 7744 that was deleted and added in revision 7614.</span><br /><br /><span style="font-family:trebuchet ms;">Deleting and adding a file in the same revision doesn't make a whole lot of sense. I'm pretty sure this was done inadvertently by the developer. In any case, doing so effectively erased the history of the file. Now svn log only shows the changes that have been made since 7614 and svn blame shows the committer of 7614 as the primary editor of the file.</span><br /><br /><span style="font-family:trebuchet ms;">Of course, we always want to accurately place blame...so we'd like to restore the history of the file.</span><br /><br /><span style="font-family:trebuchet ms;">This can be achieved by restoring a previous version of the file and then re-applying any updates to it. One side-effect is that any changes made between the delete/add revision (7614 in this case) and the new revision will be put in as one revision. Though, if you wanted to, I suppose you could work around that by re-applying the changes one by one.</span><br /><br /><span style="font-family:trebuchet ms;">Here are the svn steps I took to restore the history of the file:</span><br /><br /><span style="font-family:courier new;">svn mv some_controller.rb some_controller.rb.tmp<br /><br /></span><span style="font-family:courier new;">svn ci -m "temporary move, restoring the history of the file"<br /><br /></span><span style="font-family:courier new;">svn cp https://mysvnrepo.url/trunk/app/controllers/some_controller.rb --revision 7613 https://</span><span style="font-family:courier new;">mysvnrepo.url</span><span style="font-family:courier new;">/trunk/app/controllers/ -m "revive old version of some_controller"<br /><br /></span><span style="font-family:courier new;">svn up</span><br /><span style="font-family:courier new;"><br />svn cat some_controller.rb.tmp >some_controller.rb</span><br /><span style="font-family:courier new;"><br />svn ci -m "put new revisions back into some_controller.rb" some_controller.rb<br /><br /></span><span style="font-family:courier new;">svn del some_controller.rb.tmp<br /><br /></span><span style="font-family:courier new;">svn ci -m "remove temporary file"</span>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-22416517947084546022008-07-20T13:17:00.000-07:002008-07-22T03:26:27.107-07:00Amazon S3 - Outage<span style="font-family:trebuchet ms;">Many sites are currently feeling the pain of an Amazon S3 outage. According to http://status.aws.amazon.com/, S3 has been down since about 9AM PDT today.</span><br /><br /><span style="font-family:trebuchet ms;">Unfortunately, my company's site is one that 's impacted.</span><br /><br /><span style="font-family:trebuchet ms;">The </span><a style="font-family: trebuchet ms;" target="_amazon" href="http://status.aws.amazon.com/">AWS Service Health Dashboard</a><span style="font-family:trebuchet ms;"> is helpful but I'd prefer something that provides a more proactive notification when there's a service interruption. Something along the lines of an SMS once a service disruption is announced.</span><br /><br /><span style="font-family:trebuchet ms;">Perhaps there's something out there already that I haven't found?<br /><br /><span style="font-style: italic;"><span style="color: rgb(255, 102, 0);">UPDATE</span>: As of 5PM PDT, Amazon is reporting that the system is back to normal.<br /><br /></span></span><span style="font-family:trebuchet ms;"><span style="font-style: italic;"><span style="color: rgb(255, 102, 0);">UPDATE</span>: Here's the latest <a href="http://status.aws.amazon.com/s3us-20080720.html" target="_amazon">summary of the chain of events from Amazon</a>. Nice of them to not make every customer email for SLA credit.<br /></span></span><br /><span style="font-family:trebuchet ms;"><span style="font-style: italic;"><br /></span></span>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-71861138621958277602008-07-15T08:47:00.000-07:002008-07-15T09:10:43.677-07:00reset_column_information in cruisecontrol.rb<span style="font-family:trebuchet ms;">As I described in a </span><a style="font-family: trebuchet ms;" href="http://nathenharvey.blogspot.com/2008/07/cruisecontrolrb-fails-every-other-build.html">previous post</a><span style="font-family:trebuchet ms;">, cruisecontrol.rb was failing with every other build because of the way our migrations were written (more on why they were written that way in a later post).</span><br /><br /><span style="font-family:trebuchet ms;">Today I was able to resolve the issue by adding a new task to our list of tasks that get run when cruise completes a build.</span><br /><br /><pre><br />desc 'resets the column info for all models'<br />namespace :columns do<br />task :reset => :environment do<br /> ActiveRecord::Base.reset_column_information<br /> ActiveRecord::Base.send(:subclasses).each{|klass| klass.reset_column_information rescue nil}<br />end<br />end<br /></pre><br /><br /><span style="font-family:trebuchet ms;">Now, our cruise task looks like this:</span><br /><br /><pre><br />task :cruise do<br />['test_env_init', 'db:rollback', 'columns:reset', 'db:migrate','test', 'spec:cruise:rcov'].each do |task|<br /> Rake::Task[task].invoke<br />end<br />...<br /></pre><br /><br /><span style="font-family:trebuchet ms;">And cruisecontrol.rb is much happier...as is our development team!</span>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0tag:blogger.com,1999:blog-2265255855714252723.post-75625372552604214892008-07-02T20:08:00.000-07:002008-07-22T03:27:39.869-07:00cruisecontrol.rb fails every other build<span style="font-family:trebuchet ms;">Why does cruisecontrol.rb report that every other build fails?</span><br /><br /><span style="font-family:trebuchet ms;">Looking at the log, you see things such as:</span><br /><br /><pre><br />NoMethodError: undefined method `referring_friend' for #<user:0x2aaab3936628><br /></user:0x2aaab3936628></pre><span style="font-family:trebuchet ms;">So...where does referring_friend get introduced?</span><br /><br /><span style="font-family:trebuchet ms;">251_add_promo_to_user.rb</span><br /><pre><br />class AddPromoToUser < ActiveRecord::Migration<br /> def self.up<br /> if User.table_exists? && !User.column_names.include?('referring_friend')<br /> add_column :users, :referring_friend, :string<br /> end<br /> end<br /><br /> def self.down<br /> if User.table_exists? && User.column_names.include?('referring_friend')<br /> remove_column :users, :referring_friend<br /> end<br /><br /> end<br />end<br /></pre><br /><br /><span style="font-family:trebuchet ms;">OK, clearly this works and we have some additional checks in place. Specifically, don't add the column if it already exists and don't drop it if it's not there. Doing either of these could cause some database errors.</span><br /><br /><span style="font-family:trebuchet ms;">Nice, but we still don't know why it's failing. Let's have a look at what cruise does</span><br /><br /><span style="font-family:trebuchet ms;">custom_cc.rake</span><br /><pre><br />...<br />task :cruise do<br />['test_env_init', 'db:rollback', 'db:migrate','test', 'spec:cruise:rcov'].each do |task|<br />...<br /></pre><span style="font-style: italic;">See the problem yet?</span><br /><br /><span style="font-family:trebuchet ms;">Let's see what's happening in that cruise task.</span><br /><ul style="font-family: trebuchet ms;"><li> test_env_init - pretty simple, just sets the RAILS_ENV to test</li><li>db:rollback - runs the down for the latest migration. So in this case we</li></ul> <pre><br /> remove_column :users, :referring_friend<br /></pre><ul style="font-family: trebuchet ms;"><li>db:migrate - runs the latest migrations. So in this case we</li></ul><pre><br /> add_column :users, :referring_friend, :string<br /></pre><span style="font-family:trebuchet ms;">However...we only drop the column if it exists and we only add it if it's not already there</span><br /><br /><span style="font-family:trebuchet ms;">OK, so let's try this in our good friend, script/console:</span><br /><pre><br />$ script/console<br />Loading test environment (Rails 2.0.2)<br />>> puts User.column_names.include?('referring_friend')<br />true<br />=> nil<br />>> exit<br />$ rake db:rollback<br />(in /usr/local/cruise/cruisecontrolrb-1.2.1/projects/release_1_7/work)<br />== 251 AddPromoToUser: reverting ==============================================<br />-- remove_column(:users, :referring_friend)<br /> -> 0.1270s<br />== 251 AddPromoToUser: reverted (0.3239s) =====================================<br /><br />$ script/console<br />Loading test environment (Rails 2.0.2)<br />>> puts User.column_names.include?('referring_friend')<br />false<br />=> nil<br />>> exit<br />$ rake db:migrate<br />(in /usr/local/cruise/cruisecontrolrb-1.2.1/projects/release_1_7/work)<br />== 251 AddPromoToUser: migrating ==============================================<br />-- add_column(:users, :referring_friend, :string)<br /> -> 0.0739s<br />== 251 AddPromoToUser: migrated (0.2668s) =====================================<br /><br />$ script/console<br />Loading test environment (Rails 2.0.2)<br />>> puts User.column_names.include?('referring_friend')<br />true<br />=> nil<br />>><br /></pre><br /><span style="font-family:trebuchet ms;">Hmm...that all looks correct. But that wasn't actually a good test of what's happening because we're "Loading test environment" every time we run script/console.</span><br /><br /><span style="font-family:trebuchet ms;">Let's try that again using 2 different sell sessions.</span><br /><br /><span style="font-family:trebuchet ms;">Session 1</span><br /><pre><br />$ script/console<br />>> puts User.column_names.include?('referring_friend')<br />true<br /></pre><br /><span style="font-family:trebuchet ms;">Session 2</span><br /><pre><br />$ rake db:rollback<br />(in /usr/local/cruise/cruisecontrolrb-1.2.1/projects/release_1_7/work)<br />== 251 AddPromoToUser: reverting ==============================================<br />-- remove_column(:users, :referring_friend)<br /> -> 0.1799s<br />== 251 AddPromoToUser: reverted (0.3748s) =====================================<br /></pre><br /><span style="font-family:trebuchet ms;">Session 1</span><br /><pre><br />>> puts User.column_names.include?('referring_friend')<br />true<br /></pre><br /><span style="font-family:trebuchet ms;">Session 2</span><br /><pre><br />$ psql -U cruise_test -d cruise_test_1_7<br />$ \d users;<br /></pre><br /><span style="font-family:trebuchet ms;">*As we expected, there's no referring_friend column on the Uses table</span><br /><br /><span style="font-family:trebuchet ms;">Session 1</span><br /><pre><br />>> User.reset_column_information<br />=> nil<br />>> puts User.column_names.include?('referring_friend')<br />false<br /></pre><br /><br /><span style="font-family:trebuchet ms;">Ah ha!!</span><br /><br /><span style="font-family:trebuchet ms;">So, if we update our User model after each change, the build should <a href="http://www.youtube.com/watch?v=0pK5HmuCMBM" target="_youtube">Colt 45</a> (it works every time)</span><br /><br /><span style="font-family:trebuchet ms;">updated 251_add_promo_to_user.rb</span><br /><br /><pre><br />class AddPromoToUser < ActiveRecord::Migration<br /> def self.up<br /> if User.table_exists? && !User.column_names.include?('referring_friend')<br /> add_column :users, :referring_friend, :string<br /> User.reset_column_information<br /> end<br /> end<br /><br /> def self.down<br /> if User.table_exists? && User.column_names.include?('referring_friend')<br /> remove_column :users, :referring_friend<br /> User.reset_column_information<br /> end<br /><br /> end<br />end<br /></pre>Nathen Harveyhttp://www.blogger.com/profile/17809895065447608839noreply@blogger.com0