<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Raymond Law</title>
	
	<link>http://rayvinly.com</link>
	<description>Badminton on Rails</description>
	<lastBuildDate>Tue, 31 Mar 2009 20:02:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/rayvinly" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Intridea’s Present.ly has been nominated as a finalist in the WebWare 100 Communication Category</title>
		<link>http://feedproxy.google.com/~r/rayvinly/~3/Luui_A2qNp4/</link>
		<comments>http://rayvinly.com/articles/2009/03/31/intridea%e2%80%99s-presently-has-been-nominated-as-a-finalist-in-the-webware-100-communication-category/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 16:00:48 +0000</pubDate>
		<dc:creator>Raymond Law</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[intridea]]></category>
		<category><![CDATA[presently]]></category>

		<guid isPermaLink="false">http://rayvinly.com/?p=186</guid>
		<description>Present.ly has been nominated as a finalist in the WebWare 100 Communication Category. We&amp;#8217;re honored to be chosen from a pool of more than 5,000 applicants to be one of the 300 finalists to compete for the title.

The WebWare 100 is a yearly contest held by CNET that allows the public to pick what the [...]</description>
			<content:encoded><![CDATA[<div style="float: right;"><a href="http://www.cnet.com/html/ww/100/2009/poll/communication.html"><img alt="" src="http://www.cnet.com/html/ww/100/2009/images/voteforus/webware100-09_vote_l.jpg"/></a></div>

<p>Present.ly has been nominated as a finalist in the <a href="http://www.cnet.com/html/ww/100/2009/poll/communication.html">WebWare 100 Communication Category</a>. We&#8217;re honored to be chosen from a pool of more than 5,000 applicants to be one of the 300 finalists to compete for the title.</p>

<p>The WebWare 100 is a yearly contest held by <span class="caps"><span class="caps">CNET</span></span> that allows the public to pick what the 100 best web applications of the year are. Past winners included such products as GMail and Amazon <span class="caps">MP3, </span>so we&#8217;re very excited to be included as a finalist for this year&#8217;s selection.</p>

<p>Voting is open right now, so please <a href="http://www.cnet.com/html/ww/100/2009/poll/communication.html">vote for us</a>! We think that business micro-communication is an important next step in the future of communication, and your votes will help validate that and move it even further into the mainstream. Thanks for your support.</p><script src="http://feeds.feedburner.com/~s/rayvinly?i=http://rayvinly.com/articles/2009/03/31/intridea%e2%80%99s-presently-has-been-nominated-as-a-finalist-in-the-webware-100-communication-category/" type="text/javascript" charset="utf-8"></script><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/rayvinly?a=Luui_A2qNp4:esspHHq4HjQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=Luui_A2qNp4:esspHHq4HjQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=Luui_A2qNp4:esspHHq4HjQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=Luui_A2qNp4:esspHHq4HjQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=Luui_A2qNp4:esspHHq4HjQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=Luui_A2qNp4:esspHHq4HjQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=Luui_A2qNp4:esspHHq4HjQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=Luui_A2qNp4:esspHHq4HjQ:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rayvinly/~4/Luui_A2qNp4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rayvinly.com/articles/2009/03/31/intridea%e2%80%99s-presently-has-been-nominated-as-a-finalist-in-the-webware-100-communication-category/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://rayvinly.com/articles/2009/03/31/intridea%e2%80%99s-presently-has-been-nominated-as-a-finalist-in-the-webware-100-communication-category/</feedburner:origLink></item>
		<item>
		<title>Easy or Hard?</title>
		<link>http://feedproxy.google.com/~r/rayvinly/~3/PRADdFmxO7A/</link>
		<comments>http://rayvinly.com/articles/2009/02/25/easy-or-hard/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 08:00:09 +0000</pubDate>
		<dc:creator>Raymond Law</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://rayvinly.com/?p=146</guid>
		<description>I had the following conversation with a colleague about a client project recently.



At that moment, it strikes me that sometimes I want the easy ones but at other times I want the hard ones.  But why?  After some thoughts, I concluded with:

I want the easy ones because they are easy and quick, but [...]</description>
			<content:encoded><![CDATA[<p>I had the following conversation with a colleague about a client project recently.</p>

<p><a href="http://rayvinly.com/wp-content/uploads/2009/02/easy_or_hard.png"><img src="http://rayvinly.com/wp-content/uploads/2009/02/easy_or_hard.png" alt="easy_or_hard" title="easy_or_hard" width="616" height="356" class="aligncenter size-full wp-image-166" /></a></p>

<p>At that moment, it strikes me that sometimes I want the easy ones but at other times I want the hard ones.  But why?  After some thoughts, I concluded with:</p>

<blockquote>I want the easy ones because they are easy and quick, but annoying and boring.  And I want the hard ones because they are challenging and interesting.</blockquote>

<p>I think the following matrix describes it best:</p>

<table border="1">
  <tr>
    <td></td>
    <td>Easy</td>
    <td>Hard</td>
  </tr>
  <tr>
    <td>Annoying</td>
    <td>
      <ul>
        <li>Change copy from List Users to Search Users</li>
        <li>Rename the column from fee to amount</li>
      </ul>
    </td>
    <td>
      <ul>
        <li>Change all occurrences of <em>this</em> to <em>that</em> while <em>Replace All</em> would be too dangerous</li>
        <li>Modify all images to be half the size and with a different image format/extension</li>
      </ul>
    </td>
  </tr>
  <tr>
    <td>Interesting</td>
    <td>
    <ul>
      <li>Make sure we can seamless deploy to staging and production with ease using Capistrano</li>
      <li>Make changing the type field also changes the available choices for the month field in the form with javascript</li>
    </ul>
    </td>
    <td>
      <ul>
        <li>Charge a recurring fee with PayPal and ActiveMerchant when it is not inherently built in, and with lots of PayPal docs to read</li>
        <li>Style the site with <span class="caps">HTML, CSS, SASS </span>according to this professionally designed <span class="caps">PSD </span>with a lot of croppings</li>
      </ul>
    </td>
  </tr>
</table>
<br/>

<h3>Do you get the point?</h3>

<p>As software engineers or programmers (sometimes interchangeable terms <span class="caps">IMO</span>), we like to solve challenging and interesting problems, regardless of difficulties.  Ideally, we like everything to be in the easy and interesting quadrant, but we certainly like (sometimes prefer because it is also challenging) things in the hard and interesting quadrant as well.  We would accomplish things in these two quadrants with our fullest attention and best effort.</p>

<p>Stuff that belong to the easy and annoying, and hard and annoying quadrants bore us.  We naturally pay less attention and try to do them with spare time.  However, they still need to be done.  They become a <strong>drag</strong>.</p>

<h3>Now we understand the matrix, but what can we do about the <strong>drag</strong>?</h3>

<p>This is what I think.</p>

<p>I may feel ActiveMerchant is a joy and interesting to work with, but someone else may think it is a distraction to the project and just want to settle with using Authorize.net when it is already supported by ActiveMerchant to do recurring payment.</p>

<p>I may feel having to crop all images again and save them in a different format is a waste of my development time, but a photographer may actually enjoy such work and may even add a drop shadow to make the images look better.</p>

<p>The difference is in the <strong>interpretation</strong>.</p>

<h3>Interpretation</h3>

<p>Different people interpret the same thing differently based on their own level of interest/time/concern, &#8230;/etc.  That is a fact, not an argument.</p>

<p>In software development, instead of the project manager assigning tasks to each engineer, programmer, <span class="caps">QA, </span>you name it, based on time, skill levels, familiarities with certain code pieces, scopes, existing client relationships, <em>maybe, just maybe</em>, it is better to ask each person which of the tasks they have the most interest in and then assign tasks based on level of interest.  That way, each person on the team will put forth his/her best attention/effort to accomplish them.</p>

<h3>Potential pitfalls</h3>

<ul>
	<li> What if none of the tasks interest me?  Maybe put that person in a different project that has tasks that interest him?</li>
	<li> What if many people are interested in the same task?  Who gets to work on it?  Maybe pair programming in which several people can participate and can have inputs?</li>
	<li> If I keep picking tasks that seem easy (on the surface), would it make me look lazy?</li>
	<li> If I pick several hard tasks, I may make myself too busy.</li>
</ul>

<p>Again, we should not be blind folded by <strong>interpretaion</strong>.  I may think it is easy but someone else may think it is interesting and solve the task <em>better</em>.  I may think it is hard but since I am so interested, I may solve it with higher efficiency, hence less time.</p>

<p>The above is just a thought.  I have not actually tried it to see how well the process works.  However, since project management is so boring and annoying to so many people.  We may as well put a different <strong>interpretation</strong> to it.  It certainly is a paradigm shift in project management.</p><script src="http://feeds.feedburner.com/~s/rayvinly?i=http://rayvinly.com/articles/2009/02/25/easy-or-hard/" type="text/javascript" charset="utf-8"></script><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/rayvinly?a=PRADdFmxO7A:mXTg0pOXm9c:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=PRADdFmxO7A:mXTg0pOXm9c:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=PRADdFmxO7A:mXTg0pOXm9c:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=PRADdFmxO7A:mXTg0pOXm9c:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=PRADdFmxO7A:mXTg0pOXm9c:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=PRADdFmxO7A:mXTg0pOXm9c:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=PRADdFmxO7A:mXTg0pOXm9c:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=PRADdFmxO7A:mXTg0pOXm9c:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rayvinly/~4/PRADdFmxO7A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rayvinly.com/articles/2009/02/25/easy-or-hard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://rayvinly.com/articles/2009/02/25/easy-or-hard/</feedburner:origLink></item>
		<item>
		<title>Moving from Typo to Wordpress</title>
		<link>http://feedproxy.google.com/~r/rayvinly/~3/ZiTClMS_sbE/</link>
		<comments>http://rayvinly.com/articles/2009/02/23/moving-from-typo-to-wordpress/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 12:00:47 +0000</pubDate>
		<dc:creator>Raymond Law</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[typo]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://rayvinly.com/?p=106</guid>
		<description>I recently moved my blog from Typo to Wordpress.  Typo served well and it was written in Rails.  However, it was more difficult to upgrade and I just don&amp;#8217;t have enough time to maintain it and keep it up to date.  So it has been running at version 4.1.1 which requires Rails [...]</description>
			<content:encoded><![CDATA[<p>I recently moved my blog from <a href="http://blog.typosphere.org/">Typo</a> to <a href="http://wordpress.org/">Wordpress</a>.  Typo served well and it was written in Rails.  However, it was more difficult to upgrade and I just don&#8217;t have enough time to maintain it and keep it up to date.  So it has been running at version 4.1.1 which requires Rails 1.2.6.  So a change is imminent and I found a couple resources by <a href="http://blog.ifbydesign.com/2006/06/26/automatic-migration-from-typo-to-wordpress/">Stuart Johnston</a> and <a href="http://www.thirdbit.net/articles/2007/06/25/typo-to-wordpress-migration/">Max Newell</a>.</p>

<p>Those are <strong><span class="caps">GREAT</span></strong> starts!.  However, I had to modify the migration script for my Typo version (4.1.1) and the latest Wordpress version (2.7.1 at the time of this writing).  Fortunately, the script is just pure <span class="caps">SQL. </span> That means I had to inspect the Typo and Wordpress database structures to correctly map the tables and columns between the two databases.  It is not the funnest thing in the world though, but this has to be done.  If you have other versions of Wordpress, I recommend you upgrade to the latest version first.  That way, you don&#8217;t have to worry about Wordpress&#8217;s table structures because I already did this for you.  If you are using a different version of Typo, feel free to modify <a href="http://rayvinly.com/wp-content/uploads/2009/02/typo_4_1_1_to_wordpress_2_7_1.sql">this migration script</a> and post feedback.</p>

<p>Here are the steps that you need to take after grabbing the script:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&gt;</span> mysqldump typo_db articles_tags tags categorizations categories contents feedback <span style="color: #000000; font-weight: bold;">&gt;</span> typo.sql
<span style="color: #000000; font-weight: bold;">&gt;</span> mysql typo_db <span style="color: #000000; font-weight: bold;">&lt;</span> typo.sql
<span style="color: #000000; font-weight: bold;">&gt;</span> mysql typo_db <span style="color: #000000; font-weight: bold;">&lt;</span> typo_4_1_1_to_wordpress_2_7_1.sql</pre></div></div>
<script src="http://feeds.feedburner.com/~s/rayvinly?i=http://rayvinly.com/articles/2009/02/23/moving-from-typo-to-wordpress/" type="text/javascript" charset="utf-8"></script><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/rayvinly?a=ZiTClMS_sbE:QhbIUGv5FbI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=ZiTClMS_sbE:QhbIUGv5FbI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=ZiTClMS_sbE:QhbIUGv5FbI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=ZiTClMS_sbE:QhbIUGv5FbI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=ZiTClMS_sbE:QhbIUGv5FbI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=ZiTClMS_sbE:QhbIUGv5FbI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=ZiTClMS_sbE:QhbIUGv5FbI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=ZiTClMS_sbE:QhbIUGv5FbI:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rayvinly/~4/ZiTClMS_sbE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rayvinly.com/articles/2009/02/23/moving-from-typo-to-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://rayvinly.com/articles/2009/02/23/moving-from-typo-to-wordpress/</feedburner:origLink></item>
		<item>
		<title>PayPal Recurring Billing with ActiveMerchant in Ruby on Rails</title>
		<link>http://feedproxy.google.com/~r/rayvinly/~3/0K9uH8c0p74/</link>
		<comments>http://rayvinly.com/articles/2009/02/20/paypal-recurring-billing-with-activemerchant-in-ruby-on-rails/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 19:19:40 +0000</pubDate>
		<dc:creator>Raymond Law</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[activemerchant]]></category>
		<category><![CDATA[billing]]></category>
		<category><![CDATA[paypal]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[recurring]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://rayvinly.com/?p=87</guid>
		<description>ActiveMerchant is great and PayPal is easy to use.  A lot of us already have a PayPal account for EBay.  It works great in auctions where you pay once.  However, ActiveMerchant currently does not support PayPal recurring billing.  One requirement of a recent project is to be able to charge for [...]</description>
			<content:encoded><![CDATA[<p><a href="http://www.activemerchant.org/">ActiveMerchant</a> is great and <a href="https://developer.paypal.com/">PayPal</a> is easy to use.  A lot of us already have a PayPal account for EBay.  It works great in auctions where you pay once.  However, ActiveMerchant currently does not support PayPal recurring billing.  One requirement of a recent project is to be able to charge for a monthly or yearly subscription plan with PayPal.  Therefore, I did some googling and found that <a href="http://clockobj.co.uk/2008/09/08/ruby-on-rails-paypal-express-recurring-payments-using-active-merchant/">Jon Baker</a> has already extended ActiveMerchant to add this functionality using PayPal&#8217;s Name-Value Pair (NVP) <span class="caps">API.</span> However, as <a href="http://jadedpixel.lighthouseapp.com/projects/11599-active-merchant/tickets/17-patch-creating-paypal-recurring-payments-profile-with-activemerchant">Cody Fauser</a> pointed out, the <span class="caps">NVP API </span>was taken out from ActiveMerchant, so I had to implement that with PayPal&#8217;s <span class="caps">SOAP API.</span></p>

<p><del datetime="2009-03-31T14:53:20+00:00">First, download this <a href="http://rayvinly.com/wp-content/uploads/2009/03/paypal_express_recurring.rb">file</a> and put it in <em>vendor/plugins/active_merchant/lib/active_merchant/billing/gateways/</em>.</del>  Use the GitHub from now because maintaining a separate file download is too troublesome.  Alternatively, there&#8217;s a fork on GitHub at <a href="http://github.com/rayvinly/active_merchant/" target="_blank">http://github.com/rayvinly/active_merchant/</a>.</p>

<p>In your controller, after a user selects one of your subscription plan, the form goes to the checkout action:</p>


<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> checkout
    response = gateway.<span style="color:#9900CC;">setup_agreement</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:description</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> description, <span style="color:#ff3333; font-weight:bold;">:return_url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> return_url, <span style="color:#ff3333; font-weight:bold;">:cancel_return_url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> cancel_return_url<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#5A0A0A; font-weight:bold;">redirect_to</span> gateway.<span style="color:#9900CC;">redirect_url_for</span><span style="color:#006600; font-weight:bold;">&#40;</span>response.<span style="color:#9900CC;">token</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>




<p>This redirects the user to PayPal so he can login and read the <em>description</em> you provided.  After he confirms, he is redirected back to your application&#8217;s <em>return_url</em>, which I set it to be the complete action below.  If he cancels, he is redirected back to the <em>cancel_return_url</em>.  You can set <em>cancel_return_url</em> to be the plan selection page where he can choose a different plan.</p>

<p>If he confirms, here&#8217;s the complete action:</p>


<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> complete
    token = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:token</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    response = gateway.<span style="color:#9900CC;">create_profile</span><span style="color:#006600; font-weight:bold;">&#40;</span>token, <span style="color:#ff3333; font-weight:bold;">:description</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> description, <span style="color:#ff3333; font-weight:bold;">:start_date</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> start_date, <span style="color:#ff3333; font-weight:bold;">:frequency</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> frequency_in_months, <span style="color:#ff3333; font-weight:bold;">:amount</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> amount_in_dollars, <span style="color:#ff3333; font-weight:bold;">:auto_bill_outstanding</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Save this profile_id in your transactions table.  This is used to cancel/modify the plan in the future.</span>
    profile_id = response.<span style="color:#9900CC;">params</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;profile_id&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">if</span> response.<span style="color:#9900CC;">success</span>?
      <span style="color:#5A0A0A; font-weight:bold;">flash</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Your PayPal account was successfully set up for the &lt;strong&gt;#{description}&lt;/strong&gt; payment plan.&quot;</span>
      <span style="color:#5A0A0A; font-weight:bold;">redirect_to</span> login_path
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#5A0A0A; font-weight:bold;">flash</span>.<span style="color:#9900CC;">now</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;There was a problem setting up your PayPal account for the &lt;strong&gt;#{description}&lt;/strong&gt; payment plan&quot;</span>
      <span style="color:#5A0A0A; font-weight:bold;">render</span> cancel_url
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>




<p>I default the <em>frequency</em> to be in months and turn on <em>auto_bill_outstanding</em> because that is what I need, but you can look at the file you downloaded and the PayPal documentation to see what other options are available.  In particular, read these two <span class="caps">PDF</span>s:</p>

<ul>
	<li><a href="https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_ExpressCheckout_IntegrationGuide.pdf">Express Checkout Integration Guide</a>
</li>
	<li><a href="https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_API_Reference.pdf"><span class="caps">SOAP API</span> Developer Reference</a>
</li>
</ul>

<p>If the user wants to cancel the payment plan, a cancel action would look like:</p>


<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> cancel
    response = gateway.<span style="color:#9900CC;">cancel_profile</span><span style="color:#006600; font-weight:bold;">&#40;</span>paypal_profile_id, <span style="color:#ff3333; font-weight:bold;">:note</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Payment plan was canceled by user'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#5A0A0A; font-weight:bold;">flash</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'You have successfully canceled your membership'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>




<p><em>paypal_profile_id</em> is the profile_id you saved in the complete action from above.  Keeping this profile_id is very handy.</p>

<p>That&#8217;s it.  Enjoy making money!</p>

<p><strong><em><span class="caps">UPDATE</span> 2009-02-04</em></strong></p>

<p>I updated the extension to include a <em>credit_card</em> hash.  You will probably capture the credit card details submitted by the user in a form as in <em>params[:credit_card]</em>, but I will just create a hash to show as an example.  To make recurring payment with a credit card, just pass nil for the token (this is required, because PayPal would use the token in preference to the credit card).  Pass the <em>credit_card</em> hash as follows:</p>


<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">    credit_card = <span style="color:#CC00FF; font-weight:bold;">Hash</span>.<span style="color:#5A0A0A; font-weight:bold;">new</span>
    credit_card<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:type</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'Visa'</span>
    credit_card<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:number</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'1234567812345678'</span>
    credit_card<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:exp_month</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'07'</span>
    credit_card<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:exp_year</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'2016'</span>
    credit_card<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:cvv2</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'123'</span>
    credit_card<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:card_owner</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'John Doe'</span>
    response = gateway.<span style="color:#9900CC;">create_profile</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">nil</span>, <span style="color:#ff3333; font-weight:bold;">:credit_card</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> credit_card, <span style="color:#ff3333; font-weight:bold;">:description</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> description, <span style="color:#ff3333; font-weight:bold;">:start_date</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> start_date, <span style="color:#ff3333; font-weight:bold;">:frequency</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> frequency, <span style="color:#ff3333; font-weight:bold;">:amount</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> amount, <span style="color:#ff3333; font-weight:bold;">:auto_bill_outstanding</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>




<p>However, I got the famous <strong><span class="caps">DPRP </span>is disabled for this merchant</strong> error message when I tested it.  I did a little googling but I haven&#8217;t found the cause.  There may just be something that you have to turn on in your PayPal developer account.  I also read that it works for newer accounts only.  But since I don&#8217;t have a need for this, I didn&#8217;t look further.  If you guys know, please let me know.  I will try to update the extension as soon as possible to make it work with a credit card.</p><script src="http://feeds.feedburner.com/~s/rayvinly?i=http://rayvinly.com/articles/2009/02/20/paypal-recurring-billing-with-activemerchant-in-ruby-on-rails/" type="text/javascript" charset="utf-8"></script><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/rayvinly?a=0K9uH8c0p74:e_p4WSBR7l8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=0K9uH8c0p74:e_p4WSBR7l8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=0K9uH8c0p74:e_p4WSBR7l8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=0K9uH8c0p74:e_p4WSBR7l8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=0K9uH8c0p74:e_p4WSBR7l8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=0K9uH8c0p74:e_p4WSBR7l8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=0K9uH8c0p74:e_p4WSBR7l8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=0K9uH8c0p74:e_p4WSBR7l8:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rayvinly/~4/0K9uH8c0p74" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rayvinly.com/articles/2009/02/20/paypal-recurring-billing-with-activemerchant-in-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		<feedburner:origLink>http://rayvinly.com/articles/2009/02/20/paypal-recurring-billing-with-activemerchant-in-ruby-on-rails/</feedburner:origLink></item>
		<item>
		<title>Sanitize your output in Ruby on Rails</title>
		<link>http://feedproxy.google.com/~r/rayvinly/~3/R3osTdL9NsU/</link>
		<comments>http://rayvinly.com/articles/2008/10/30/sanitize-your-output-in-ruby-on-rails/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 14:43:02 +0000</pubDate>
		<dc:creator>Raymond Law</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[footnotes]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[safe_erb]]></category>
		<category><![CDATA[sanitize]]></category>

		<guid isPermaLink="false" />
		<description>We all know about the holy h() method that escapes your output when you do .  But how many of us can claim we remember to use it where it&amp;#8217;s appropriate during development 100% of the time?  Can you swear you&amp;#8217;ve never missed one?  Moreover, it&amp;#8217;s such a mental distraction to think [...]</description>
			<content:encoded><![CDATA[<p>We all know about the holy h() method that escapes your output when you do <%=h blah %>.  But how many of us can claim we remember to use it where it&#8217;s appropriate during development 100% of the time?  Can you swear you&#8217;ve never missed one?  Moreover, it&#8217;s such a mental distraction to think logic and h() at the same time.  And when you take over a Rails project in the middle, how can you ensure the previous developers use h()?</p>

<p>Here&#8217;s the rescue.</p>

<p><a href="http://github.com/pelargir/safe_erb">safe_erb</a> + <a href="http://github.com/drnic/rails-footnotes">footnotes</a></p>

<p>I don&#8217;t think I need to explain more.  Just use it and you will find all those places where you should sanitize your output with h(), sanitize(), and untaint(), &#8230;etc.</p><script src="http://feeds.feedburner.com/~s/rayvinly?i=http://rayvinly.com/articles/2008/10/30/sanitize-your-output-in-ruby-on-rails/" type="text/javascript" charset="utf-8"></script><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/rayvinly?a=R3osTdL9NsU:Ro2eosQjYao:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=R3osTdL9NsU:Ro2eosQjYao:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=R3osTdL9NsU:Ro2eosQjYao:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=R3osTdL9NsU:Ro2eosQjYao:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=R3osTdL9NsU:Ro2eosQjYao:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=R3osTdL9NsU:Ro2eosQjYao:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=R3osTdL9NsU:Ro2eosQjYao:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=R3osTdL9NsU:Ro2eosQjYao:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rayvinly/~4/R3osTdL9NsU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rayvinly.com/articles/2008/10/30/sanitize-your-output-in-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://rayvinly.com/articles/2008/10/30/sanitize-your-output-in-ruby-on-rails/</feedburner:origLink></item>
		<item>
		<title>RailsRumble 2008</title>
		<link>http://feedproxy.google.com/~r/rayvinly/~3/pZAUdAHX-9I/</link>
		<comments>http://rayvinly.com/articles/2008/10/19/railsrumble-2008/#comments</comments>
		<pubDate>Sun, 19 Oct 2008 20:05:40 +0000</pubDate>
		<dc:creator>Raymond Law</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[railsrumble]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false" />
		<description>We just finished the Lyricist application for RailsRumble 2008 with 3 other Intridea folks.  Here are some observations:



Keep the idea small and achievable &amp;#8211; There are only 48 hours, so you can&amp;#8217;t build the next Google.  And there&amp;#8217;s pressure.  Try to keep your idea small and make sure you can accomplish it. [...]</description>
			<content:encoded><![CDATA[<p>We just finished the <a href="http://lyricistapp.com">Lyricist</a> application for <a href="http://railsrumble.com">RailsRumble 2008</a> with 3 other <a href="http://intridea.com">Intridea</a> folks.  Here are some observations:</p>


<ul>
<li><strong>Keep the idea small and achievable</strong> &#8211; There are only 48 hours, so you can&#8217;t build the next Google.  And there&#8217;s pressure.  Try to keep your idea small and make sure you can accomplish it.  You have to deploy a finished product in order to have any chance of winning.  So stop day dreaming about cool extra features because you won&#8217;t get that implemented.</li>
</ul>




<ul>
<li><strong>Prior planning is the key</strong> &#8211; We barely had any because we had decided on the idea the day before the rumble began.  When the competition started, people don&#8217;t know who&#8217;s doing what and it was kinda a mess.  Fortunately we had a campfire room where all conversation happen, so we can kind of iron out the issues.  However, better preparation and team cohesiveness would have helped a great deal in communication.</li>
</ul>




<ul>
<li><strong>Deploy early</strong> &#8211; I&#8217;ve seen too many deployment problems came up before, so I took the initiative to make sure we could deploy as soon as the competition began.  It helped tremendously because we never had to worry about if we could deploy before time expired.  While you are fixing last minute bugs and the pressure, it would have been tough to set up a server and deploy flawlessly.</li>
</ul>




<ul>
<li><strong>A lot of scaffolding</strong> &#8211; I took full advantage of Rails scaffolding.  There&#8217;s just no time to reinvent the wheels when all the restful model and controller methods are already available with just one command.  You use plugins and gems for the same reason, right?  So, don&#8217;t be stupid.</li>
</ul>




<ul>
<li><strong>Conflicts</strong> &#8211; The bigger your team, the more conflicts there would be when people check in and out.  We were writing a new application, so people were editing the same files.  Now, if you organize and assign work to people as in a regular project, conflicts don&#8217;t usually happen and even if they do occur, it is trivial to resolve.  However, when you are rumbling, you will step on one another&#8217;s toes.  I can guarantee you that.</li>
</ul>




<ul>
<li><strong>Forget about writing tests</strong> &#8211; Look, I am in support of agile and test-driven development, with one exception.  That is, you are not participating in RailsRumble.  There&#8217;s just no time for it.  If you are a good enough programmer, you can build a small application with no tests.  If you can&#8217;t, I don&#8217;t want to work with you.  Writing tests for a new application starting from scratch in just 48 hours is simple not feasible.  No bargain!</li>
</ul>




<ul>
<li><strong>No ticketing system like Unfuddle and Lighthouse</strong> &#8211; One team member had tried to use Unfuddle to create tickets to get ourselves more organized.  While it was a sincere attempt, it simply didn&#8217;t work.  There&#8217;s no time to accept a ticket, create a new ticket, &#8230;  We pretty much abandoned it soon after we started.</li>
</ul>




<ul>
<li><strong>Nice to have a designer</strong>: &#8211; It is very nice if you have a designer on you team because it&#8217;s hard to wear two hats in 48 hours.  Design work can draw your focus away from development.</li>
</ul>



<p>Now that I&#8217;ve given you my insights for next year&#8217;s RailsRumble.  As a token of appreciation, please <a href="http://railsrumble.com/teams/the-unstable-isotopes">vote for us</a>!</p>

<p><strong><span class="caps">UPDATE</span> 2008/10/20</strong></p>

<p><em>One more thought on RailsRumble the day after:</em></p>

<p>Numerous projects that I worked with before never deploy quickly, let alone in 48 hours.  I think it&#8217;s refreshing and rewarding to have something built and deployed so quickly.  It is true that we have to cut many features in order to deploy a first version, but lesser is better than never.  I think many other projects can try to deploy early and often and just go through more iterations and get feedbacks from users and customers.  The whole application doesn&#8217;t need to be finished.  Even if you only have login and logout, you can still deploy.  Add the next feature, deploy again.  That way, you aren&#8217;t keeping the features to yourself.  You can get feedback from users to see what improvements they are looking for and may even lead you to implement the real features that they truly want.</p><script src="http://feeds.feedburner.com/~s/rayvinly?i=http://rayvinly.com/articles/2008/10/19/railsrumble-2008/" type="text/javascript" charset="utf-8"></script><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/rayvinly?a=pZAUdAHX-9I:Ro2eosQjYao:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=pZAUdAHX-9I:Ro2eosQjYao:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=pZAUdAHX-9I:Ro2eosQjYao:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=pZAUdAHX-9I:Ro2eosQjYao:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=pZAUdAHX-9I:Ro2eosQjYao:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=pZAUdAHX-9I:Ro2eosQjYao:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=pZAUdAHX-9I:Ro2eosQjYao:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=pZAUdAHX-9I:Ro2eosQjYao:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rayvinly/~4/pZAUdAHX-9I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rayvinly.com/articles/2008/10/19/railsrumble-2008/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://rayvinly.com/articles/2008/10/19/railsrumble-2008/</feedburner:origLink></item>
		<item>
		<title>Google Badminton</title>
		<link>http://feedproxy.google.com/~r/rayvinly/~3/wgpBf9fj_GE/</link>
		<comments>http://rayvinly.com/articles/2008/08/15/google-badminton/#comments</comments>
		<pubDate>Fri, 15 Aug 2008 23:10:58 +0000</pubDate>
		<dc:creator>Raymond Law</dc:creator>
				<category><![CDATA[Badminton]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false" />
		<description></description>
			<content:encoded><![CDATA[<p><img src="http://img.skitch.com/20080816-ebf28tbb45xfdbdgedhsigu7t.png" alt="" /></p><script src="http://feeds.feedburner.com/~s/rayvinly?i=http://rayvinly.com/articles/2008/08/15/google-badminton/" type="text/javascript" charset="utf-8"></script><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/rayvinly?a=wgpBf9fj_GE:Ro2eosQjYao:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=wgpBf9fj_GE:Ro2eosQjYao:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=wgpBf9fj_GE:Ro2eosQjYao:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=wgpBf9fj_GE:Ro2eosQjYao:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=wgpBf9fj_GE:Ro2eosQjYao:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=wgpBf9fj_GE:Ro2eosQjYao:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=wgpBf9fj_GE:Ro2eosQjYao:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=wgpBf9fj_GE:Ro2eosQjYao:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rayvinly/~4/wgpBf9fj_GE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rayvinly.com/articles/2008/08/15/google-badminton/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://rayvinly.com/articles/2008/08/15/google-badminton/</feedburner:origLink></item>
		<item>
		<title>Capistrano Deployment Recipes</title>
		<link>http://feedproxy.google.com/~r/rayvinly/~3/NaAFjET2d1c/</link>
		<comments>http://rayvinly.com/articles/2008/08/04/capistrano-deployment-recipes/#comments</comments>
		<pubDate>Mon, 04 Aug 2008 16:55:08 +0000</pubDate>
		<dc:creator>Raymond Law</dc:creator>
				<category><![CDATA[Dealistic]]></category>
		<category><![CDATA[Entrepreneurship]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[slicehost]]></category>

		<guid isPermaLink="false" />
		<description>Dealistic was first deployed to Slicehost when we were testing it on staging.  However, I only got the 256 slice and low memory is a big problem for Ruby and Mongrel.  We&amp;#8217;ve moved to Amazon EC2 when we launched.  It is running rock solid and we don&amp;#8217;t run out of memory again, [...]</description>
			<content:encoded><![CDATA[<p><a href="http://dealistic.com/">Dealistic</a> was first deployed to <a href="http://www.slicehost.com/">Slicehost</a> when we were testing it on staging.  However, I only got the 256 slice and low memory is a big problem for Ruby and Mongrel.  We&#8217;ve moved to <a href="http://www.amazon.com/gp/browse.html?node=201590011">Amazon <span class="caps">EC2</span></a> when we launched.  It is running rock solid and we don&#8217;t run out of memory again, at least for now <img src='http://rayvinly.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>

<p>As a result of all these, I wrote two <a href="http://www.capify.org/">Capistrano</a> recipes for deployment, for both Slicehost and <span class="caps">EC2. </span> We also use <a href="http://github.com/">GitHub</a> for version control.  I think these deployment recipes may be helpful to others.  So here they are:</p>


<ul>
<li><a href="http://rayvinly.com/wp-content/uploads/2009/02/deploy_slicehost.rb">deploy.rb for Slicehost</a></li>
<li><a href="http://rayvinly.com/wp-content/uploads/2009/02/deploy_ec2.rb">deploy.rb for <span class="caps">EC2</span></a></li>
</ul>



<p>We wrote some custom Capistrano tasks to copy over configuration files, symlink plugins, start/stop <a href="http://backgroundrb.rubyforge.org/">BackgrounDRb</a>, and a custom maintenance page.  But these things are optional.  It should be simple to add/remove things as you see fit.</p><script src="http://feeds.feedburner.com/~s/rayvinly?i=http://rayvinly.com/articles/2008/08/04/capistrano-deployment-recipes/" type="text/javascript" charset="utf-8"></script><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/rayvinly?a=NaAFjET2d1c:Ro2eosQjYao:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=NaAFjET2d1c:Ro2eosQjYao:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=NaAFjET2d1c:Ro2eosQjYao:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=NaAFjET2d1c:Ro2eosQjYao:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=NaAFjET2d1c:Ro2eosQjYao:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=NaAFjET2d1c:Ro2eosQjYao:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=NaAFjET2d1c:Ro2eosQjYao:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=NaAFjET2d1c:Ro2eosQjYao:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rayvinly/~4/NaAFjET2d1c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rayvinly.com/articles/2008/08/04/capistrano-deployment-recipes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://rayvinly.com/articles/2008/08/04/capistrano-deployment-recipes/</feedburner:origLink></item>
		<item>
		<title>Dealistic is launched</title>
		<link>http://feedproxy.google.com/~r/rayvinly/~3/neqGcczHSa8/</link>
		<comments>http://rayvinly.com/articles/2008/07/29/dealistic-is-launched/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 02:42:01 +0000</pubDate>
		<dc:creator>Raymond Law</dc:creator>
				<category><![CDATA[Dealistic]]></category>
		<category><![CDATA[Entrepreneurship]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[buy]]></category>
		<category><![CDATA[coupon]]></category>
		<category><![CDATA[deal]]></category>

		<guid isPermaLink="false" />
		<description>Andrew and I have been working on a new site Dealistic after our work at OnMyList.

We&amp;#8217;ve also put up a screencast to show off our features (HUGE thanks to Sherry)

				

It lets you find deals by specifying a list of tags and it can notify you by email, RSS feed, and/or SMS when new deals appear [...]</description>
			<content:encoded><![CDATA[<p><img src="http://dealistic.com/images/logo.gif" alt="" /></p>

<p><a href="http://blog.andrewng.com">Andrew</a> and I have been working on a new site <a href="http://dealistic.com">Dealistic</a> after our work at <a href="http://www.onmylist.com">OnMyList</a>.</p>

<p>We&#8217;ve also put up a screencast to show off our features (HUGE thanks to <a href="http://sherrysun.com/">Sherry</a>)</p>

<p><object width="400" height="300">	<param name="allowfullscreen" value="true" />	<param name="allowscriptaccess" value="always" />	<param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=1427503&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" />	<embed src="http://www.vimeo.com/moogaloop.swf?clip_id=1427503&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object></p>

<p>It lets you find deals by specifying a list of tags and it can notify you by email, <span class="caps">RSS </span>feed, and/or <span class="caps">SMS </span>when new deals appear that match your tags.</p>

<p>We made the site because we often need to find deals on things we want to buy but we spend way too much time looking for irrelevant deals on a lot of different sites.  With <a href="http://dealistic.com">Dealistic</a>, what you get is what you want.</p>

<p><strong>Never miss a deal because you don&#8217;t have time to find it!  Just add a tag at <a href="http://dealistic.com">Dealistic</a> and we will let you know when a deal that you are looking for appears.</strong></p>

<p>We also have a <a href="http://getsatisfaction.com/dealisticcom">feedback tool</a> that we hope you can give us suggestions to do better.</p><script src="http://feeds.feedburner.com/~s/rayvinly?i=http://rayvinly.com/articles/2008/07/29/dealistic-is-launched/" type="text/javascript" charset="utf-8"></script><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/rayvinly?a=neqGcczHSa8:Ro2eosQjYao:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=neqGcczHSa8:Ro2eosQjYao:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=neqGcczHSa8:Ro2eosQjYao:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=neqGcczHSa8:Ro2eosQjYao:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=neqGcczHSa8:Ro2eosQjYao:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=neqGcczHSa8:Ro2eosQjYao:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=neqGcczHSa8:Ro2eosQjYao:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=neqGcczHSa8:Ro2eosQjYao:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rayvinly/~4/neqGcczHSa8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rayvinly.com/articles/2008/07/29/dealistic-is-launched/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://rayvinly.com/articles/2008/07/29/dealistic-is-launched/</feedburner:origLink></item>
		<item>
		<title>Home-made Strawberry Banana Rendezvous</title>
		<link>http://feedproxy.google.com/~r/rayvinly/~3/Y6HXBbLLGko/</link>
		<comments>http://rayvinly.com/articles/2008/07/28/home-made-strawberry-banana-rendezvous/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 18:11:18 +0000</pubDate>
		<dc:creator>Raymond Law</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[coldstone]]></category>
		<category><![CDATA[dessert]]></category>
		<category><![CDATA[icecream]]></category>

		<guid isPermaLink="false" />
		<description>Today I was stressed out while working because of the construction drilling noise near my house (I am working from home for Intridea).  So I took a break, and tried to make a dessert aka Cold Stone Creamery &amp;#8217;s Strawberry Banana Rendezvous.

Ingredients I used:



Turkey Hill strawberry ice-cream &amp;#8211; not the greatest ice-cream brand but [...]</description>
			<content:encoded><![CDATA[<p>Today I was stressed out while working because of the construction drilling noise near my house (I am working from home for <a href="http://www.intridea.com">Intridea</a>).  So I took a break, and tried to make a dessert aka <a href="http://www.coldstonecreamery.com">Cold Stone Creamery</a> &#8217;s Strawberry Banana Rendezvous.</p>

<p>Ingredients I used:</p>


<ul>
<li><a href="http://www.turkeyhill.com">Turkey Hill</a> strawberry ice-cream &#8211; not the greatest ice-cream brand but that&#8217;s what was on sale at <a href="http://www.wegmans.com">Wegmans</a> last night&#8230;</li>
<li>Hersey chocolate chips</li>
<li>A few Strawberries</li>
<li>Half of a banana &#8211; I ate the other half separately</li>
</ul>



<p>I put all these in a bowl and mix it to gether for one minute.  The taste comes close.  However, it doesn&#8217;t resemble ice-cream anymore as I am missing one huge ingredient &#8211; the &#8220;cold stone.&#8221;</p>

<p>I guess the &#8220;cold stone&#8221; must be needed to keep the ice-cream ice-cream during the mixing process.  The result was more like a milk shake than ice-cream.  I still ate it all since I am a big ice-cream lover and I couldn&#8217;t just throw it away to the trash!  I mean, it is going to look like that in my stomach anyway, right?</p>

<p>So if anyone has a substitute for a cold stone, let me know.  This is what I think can simulate the &#8220;cold stone.&#8221;</p>


<ul>
<li>Put the bowl in the freezer and take it out only when you are ready to begin the mixing process.</li>
<li>Take the ice-cream out at the last possible second.</li>
<li>Surround the bowl with a box of ice.</li>
<li>It is probably a good idea to max your AC or do this only in the winter.  A few degrees below freezing and being outdoor in Canada may help too.</li>
</ul>

<script src="http://feeds.feedburner.com/~s/rayvinly?i=http://rayvinly.com/articles/2008/07/28/home-made-strawberry-banana-rendezvous/" type="text/javascript" charset="utf-8"></script><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/rayvinly?a=Y6HXBbLLGko:Ro2eosQjYao:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=Y6HXBbLLGko:Ro2eosQjYao:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/rayvinly?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=Y6HXBbLLGko:Ro2eosQjYao:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=Y6HXBbLLGko:Ro2eosQjYao:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=Y6HXBbLLGko:Ro2eosQjYao:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=Y6HXBbLLGko:Ro2eosQjYao:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/rayvinly?a=Y6HXBbLLGko:Ro2eosQjYao:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/rayvinly?i=Y6HXBbLLGko:Ro2eosQjYao:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/rayvinly/~4/Y6HXBbLLGko" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rayvinly.com/articles/2008/07/28/home-made-strawberry-banana-rendezvous/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://rayvinly.com/articles/2008/07/28/home-made-strawberry-banana-rendezvous/</feedburner:origLink></item>
	</channel>
</rss>
