<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>lindsaar.net - Home</title>
  <id>tag:lindsaar.net,2008:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://lindsaar.net/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://lindsaar.net/" rel="alternate" type="text/html"/>
  <updated>2008-05-05T00:30:07Z</updated>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-05-05:378</id>
    <published>2008-05-05T00:25:00Z</published>
    <updated>2008-05-05T00:30:07Z</updated>
    <link href="http://lindsaar.net/2008/5/5/hard-reset-rebooting-a-soekris-net-5501" rel="alternate" type="text/html"/>
    <title>Hard Reset / Rebooting a Soekris Net 5501</title>
<summary type="html">&lt;p&gt;If you have a Soekris Net5501, sometimes they will not reboot when you tell them to.  Hanging just after the memory test.  Here is how you force them to reboot.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;If you have a Soekris Net5501, sometimes they will not reboot when you tell them to.  Hanging just after the memory test.  Here is how you force them to reboot.&lt;/p&gt;
&lt;p&gt;The only thing you have to have is a serial connection to the console port of the Soekris.  Any good network design should give you some sort of console connection as a backup path, if you don&#8217;t have access to the console on your box from remote, you might want to work out how you can do this.&lt;/p&gt;


	&lt;p&gt;Having a modem with dial back is one way, but I usually cross connect boxes together so that if one fails, I can get to the console via the serial port of another.  This way, I can always get to the console of any unit that dies.&lt;/p&gt;


	&lt;p&gt;So, the reset command is quite easy.  Connect to the console and type &#8220;&lt;ins&gt;+&lt;/ins&gt;&#8221; then wait about 2 seconds and type &#8220;POWER&#8221;&lt;/p&gt;


	&lt;p&gt;This will turn the Soekris off, wait about 5 seconds, and then turn it back on again.&lt;/p&gt;


	&lt;p&gt;This is a life saver when you have a CF card that does not initialize in time for the box to boot.&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-26:343</id>
    <published>2008-04-26T13:39:00Z</published>
    <updated>2008-04-26T13:56:42Z</updated>
    <category term="Ruby on Rails"/>
    <category term="Ruby on Rails Tips"/>
    <link href="http://lindsaar.net/2008/4/26/tip-15-read-other-people-s-code" rel="alternate" type="text/html"/>
    <title>Tip #15 - Read Other People's Code</title>
<summary type="html">&lt;p&gt;It is a great tip, and one I do fairly often, go download some code and read it until you understand it.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;It is a great tip, and one I do fairly often, go download some code and read it until you understand it.&lt;/p&gt;
&lt;p&gt;This is a short tip!&lt;/p&gt;


	&lt;h4&gt;Sometimes you just need a different perspective.&lt;/h4&gt;


	&lt;p&gt;Getting and installing say, &lt;a href=&quot;http://svn.techno-weenie.net/projects/plugins/restful_authentication/&quot;&gt;restful authentication&lt;/a&gt;, or downloading the &lt;a href=&quot;http://svn.joyent.com/opensource/&quot;&gt;Joyent Connector&lt;/a&gt; and reading through some of the code will give you lots of good ideas about where to go and what to do in your own application development.&lt;/p&gt;


	&lt;p&gt;A great one for the intermediate Railsite is the &lt;a href=&quot;http://sample.caboo.se/&quot;&gt;Caboose sample apps&lt;/a&gt;  These really give you a new view on how to make an app.&lt;/p&gt;


	&lt;p&gt;Anyway, happy hunting!&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-23:318</id>
    <published>2008-04-23T11:02:00Z</published>
    <updated>2008-04-23T11:14:07Z</updated>
    <category term="Ruby on Rails"/>
    <category term="Ruby on Rails Tips"/>
    <link href="http://lindsaar.net/2008/4/23/tip-14-custom-error-messages-in-validations" rel="alternate" type="text/html"/>
    <title>Tip #14 - Custom Error Messages in Validations</title>
<summary type="html">&lt;p&gt;If you use Rails, you sometimes get a situation where the custom error messages just don&#8217;t work, here is how you can fix it&#8230;&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;If you use Rails, you sometimes get a situation where the custom error messages just don&#8217;t work, here is how you can fix it&#8230;&lt;/p&gt;
&lt;p&gt;Say you have a model with a field called &#8216;country_iso&#8217; which specifies the &lt;span class=&quot;caps&quot;&gt;ISO&lt;/span&gt; value of the country the person belongs to.&lt;/p&gt;


	&lt;p&gt;Database design concerns aside (you should really have it as country_id and a separate country_iso field) you might be stuck with this situation from a legacy database (like I was).&lt;/p&gt;


	&lt;p&gt;As this is a required field, you set the following in your model:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;User&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  validates_presence_of &lt;span class=&quot;sy&quot;&gt;:country_iso&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;So, you go ahead and make a form which presents the country as just a select box, because you don&#8217;t want your users to worry about if Thailand is TH or TL, but then you don&#8217;t specify a country and the error message comes back to the user in nice big letters:&lt;/p&gt;


	&lt;p&gt;&lt;span&gt;Country Iso can&#8217;t be blank&lt;/span&gt;&lt;/p&gt;


	&lt;h4&gt;Ugh!&lt;/h4&gt;


	&lt;p&gt;Aside from the fact that Iso is capitalized badly, how many of &lt;span class=&quot;caps&quot;&gt;YOUR&lt;/span&gt; users know that it stands for &#8220;International Standards Organization&#8221; and that a Country &lt;span class=&quot;caps&quot;&gt;ISO&lt;/span&gt; is usually a two letter representation of the country?  I&#8217;d wager about 3 of them have some idea :)&lt;/p&gt;


	&lt;p&gt;So you go in and change the validates line to:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;User&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  validates_presence_of &lt;span class=&quot;sy&quot;&gt;:country_iso&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:message&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Country can't be blank&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Do your test again, and now you get:&lt;/p&gt;


	&lt;p&gt;&lt;span&gt;Country Iso Country can&#8217;t be blank&lt;/span&gt;&lt;/p&gt;


	&lt;p&gt;Nup.. that&#8217;d didn&#8217;t really fix it.&lt;/p&gt;


	&lt;p&gt;Fortunately, the fix is easy:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;User&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  validate &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |user|&lt;tt&gt;
&lt;/tt&gt;    user.errors.add_to_base(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Country can't be blank&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; user.country_iso.blank?&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Now, reload your view and you&#8217;ll get:&lt;/p&gt;


	&lt;p&gt;&lt;span&gt;Country can&#8217;t be blank&lt;/span&gt;&lt;/p&gt;


	&lt;p&gt;Much better!&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-22:317</id>
    <published>2008-04-22T12:51:00Z</published>
    <updated>2008-04-23T11:14:36Z</updated>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <category term="Ruby on Rails Tips"/>
    <link href="http://lindsaar.net/2008/4/22/tip-13-bangbang-transformations" rel="alternate" type="text/html"/>
    <title>Tip #13 - BangBang Transformations!</title>
<summary type="html">&lt;p&gt;Ruby is marvelous, everything evaluates.  Which means a lot of the time, you can get away with things like &#8216;if @user&#8230;&#8221; and just depend on the existence of the @user var.  But what if you just really need a Boolean true or false?  Here is a little pattern you can use to do this&#8230;&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Ruby is marvelous, everything evaluates.  Which means a lot of the time, you can get away with things like &#8216;if @user&#8230;&#8221; and just depend on the existence of the @user var.  But what if you just really need a Boolean true or false?  Here is a little pattern you can use to do this&#8230;&lt;/p&gt;
&lt;h4&gt;Where two wrongs make a right?&lt;/h4&gt;


	&lt;p&gt;Ruby you have the case that &lt;span class=&quot;caps&quot;&gt;EVERYTHING&lt;/span&gt; except nil and false are &#8220;truthy&#8221; (which means, they evaluate to true in a condition).&lt;/p&gt;


	&lt;p&gt;So that is why something like this can work in Ruby:&lt;/p&gt;


&lt;pre class=&quot;shell&quot;&gt;
irb(main):001:0&amp;gt; user = &quot;Mikel&quot; 
=&amp;gt; &quot;Mikel&quot; 
irb(main):002:0&amp;gt; if user
irb(main):003:1&amp;gt;   puts &quot;Hello #{user}&quot; 
irb(main):004:1&amp;gt; end 
Hello Mikel
&lt;/pre&gt;

	&lt;p&gt;But the &#8220;value&#8221; of users in that if statement is still &#8216;Mikel&#8217;&lt;/p&gt;


	&lt;p&gt;What if you had a method in a rails model like this:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;logged_in?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;pc&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; logged_in_date != &lt;span class=&quot;pc&quot;&gt;nil&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;That says &#8220;Return true if the logged_in_date is not nil, otherwise return nil.&lt;/p&gt;


	&lt;p&gt;The problem with this, is that if the logged_in_date is &lt;em&gt;already&lt;/em&gt; nil, the method will return nil, not false.  And nil does not equal false in all cases.&lt;/p&gt;


	&lt;p&gt;A better way to write this would be to use the logical &lt;span class=&quot;caps&quot;&gt;NOT&lt;/span&gt; operator, you might know that a ! in front of any variable is a logical &lt;span class=&quot;caps&quot;&gt;NOT&lt;/span&gt; operator.  This means, it takes whatever the value is and returns the opposite as a true or false.  So we get stuff like this:&lt;/p&gt;


&lt;pre class=&quot;shell&quot;&gt;
irb(main):001:0&amp;gt; true
=&amp;gt; true
irb(main):002:0&amp;gt; !true
=&amp;gt; false
irb(main):003:0&amp;gt; 1 == 1
=&amp;gt; true
irb(main):004:0&amp;gt; !(1 == 1)
=&amp;gt; false
&lt;/pre&gt;

	&lt;p&gt;Easy enough.&lt;/p&gt;


	&lt;p&gt;So &lt;span class=&quot;caps&quot;&gt;NOT&lt;/span&gt; true equals false.  But &lt;span class=&quot;caps&quot;&gt;NOT NOT&lt;/span&gt; true equals true.  And &lt;span class=&quot;caps&quot;&gt;NOT NOT&lt;/span&gt; (anything except nil and false) equals true.  And &lt;span class=&quot;caps&quot;&gt;NOT NOT&lt;/span&gt; anything that is nil or false equals false.  Confused?  Let me show you the same &#8220;logged_in?&#8221; method with some ruby goodness:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;logged_in?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  !!logged_in_date&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;What this now says is that if the logged_in_date is nil, then apply &lt;span class=&quot;caps&quot;&gt;NOT&lt;/span&gt; to that (which gives you true) and apply &lt;span class=&quot;caps&quot;&gt;NOT&lt;/span&gt; to that (which will give you false) so in that case it will return false, which is what you want!&lt;/p&gt;


	&lt;p&gt;On the other hand, if logged_in_date is &lt;span class=&quot;caps&quot;&gt;ANY&lt;/span&gt; value (string, date, anything) then you apply &lt;span class=&quot;caps&quot;&gt;NOT&lt;/span&gt; to that and you get false, apply &lt;span class=&quot;caps&quot;&gt;NOT&lt;/span&gt; again and you get true.  Which is also what you want.&lt;/p&gt;


	&lt;p&gt;So instead of returning true or nil, that method will now return true or false, just as we expect.&lt;/p&gt;


	&lt;p&gt;Not bad for two exclamation marks!&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-21:313</id>
    <published>2008-04-21T00:30:00Z</published>
    <updated>2008-04-21T00:46:09Z</updated>
    <category term="Ruby on Rails Tips"/>
    <link href="http://lindsaar.net/2008/4/21/tip-12-html-and-http-are-your-friends" rel="alternate" type="text/html"/>
    <title>Tip #12 - HTML and HTTP are Your Friends</title>
<summary type="html">&lt;p&gt;What is an &amp;lt;em&amp;gt; tag? How do you manually make a select box?  What about a multi value select box?  Do you know the difference between a &amp;lt;submit&amp;gt; tag and a &amp;lt;button&amp;gt; tag?  Can you hand code a form to make a restful post to one of your Rails controllers?  If you can&#8217;t do all the above with plain &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; and no rails helpers or don&#8217;t know the difference between a &lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt; request and when you use either, then you need to read on.  If you can, feel free to skip to the next section.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;What is an &amp;lt;em&amp;gt; tag? How do you manually make a select box?  What about a multi value select box?  Do you know the difference between a &amp;lt;submit&amp;gt; tag and a &amp;lt;button&amp;gt; tag?  Can you hand code a form to make a restful post to one of your Rails controllers?  If you can&#8217;t do all the above with plain &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; and no rails helpers or don&#8217;t know the difference between a &lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt; request and when you use either, then you need to read on.  If you can, feel free to skip to the next section.&lt;/p&gt;
&lt;p&gt;This is part of my 8-Part tip-a-thon on the &lt;a href=&quot;http://www.lindsaar.net/2008/4/17/tip-8-how-learn-ruby-on-rails&quot;&gt;Must Know Facets of Ruby on Rails&lt;/a&gt;.  If you haven&#8217;t already, please read the first part and then come forward (there is a link at the bottom of each article that links to the next)&lt;/p&gt;


	&lt;h4&gt;Learn All About &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;&lt;/h4&gt;


	&lt;p&gt;You would think it would go without saying, but to do Ruby on Rails, you are &lt;span class=&quot;caps&quot;&gt;GOING&lt;/span&gt; to need to know what the old workhorse, &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;, is and how to use it.&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; is what we use for everything on the web.  Unless you are not coding for the web and making an entirely resourceful application that only talks via &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; or some other protocol, you will need to understand &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;.  After all, it is the presentation layer and with a bad, unusable, unintuitive design, it doesn&#8217;t matter how good your application is, your users won&#8217;t use it.&lt;/p&gt;


	&lt;p&gt;Lets give some examples.&lt;/p&gt;


	&lt;p&gt;You all know Rails has a form helper.  This thing is a god-send. It turns making an entire, fully functioning post request into:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&amp;lt;&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;%-&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; form_for @user &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;-&lt;/span&gt;&lt;/span&gt;%&amp;gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;But unless you know what that tag is actually generating, you will always go over that and look at it and glibly say &#8220;Oh, yeah, that makes the user form&#8221; and then when something about it doesn&#8217;t work, you are in trouble.&lt;/p&gt;


	&lt;p&gt;What about the select tag?  Rails again to the rescue:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&amp;lt;%= collection_select &lt;span class=&quot;iv&quot;&gt;@person&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:job&lt;/span&gt;, &lt;span class=&quot;iv&quot;&gt;@jobs&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:id&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:name&lt;/span&gt; -&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;TADA&lt;/span&gt;&lt;/strong&gt;, you suddenly have a complete select box with all the jobs a person can have with their existing job already selected.&lt;/p&gt;


	&lt;p&gt;This is all good until you need to go outside the square, then your underlying knowledge of how all the &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; works (or lack of it) will come up and bite you from behind.&lt;/p&gt;


	&lt;p&gt;So how do you get around this?&lt;/p&gt;


	&lt;p&gt;Well, believe it or not, your web browser &#8216;show source&#8217; function is a &lt;span class=&quot;caps&quot;&gt;VERY&lt;/span&gt; good start.  Make a form and then open up the browser and have a look at the generated code.  Then even go as far as not using the helpers and manually type the &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; code into the view and observe that it &lt;strong&gt;gasp&lt;/strong&gt; still looks and works the same as using the helper?????&lt;/p&gt;


	&lt;p&gt;Too many times in forums and online, I have seen people (and myself too) try to shoe horn a helper into doing exactly what they want, instead of just coding it in &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; and being done with it (or making their own helper).&lt;/p&gt;


	&lt;p&gt;There are many advantages with the Rails helpers, especially with regards to code maintainability, and that is, if you use helpers you are agreeing to code in a certain manner that will allow yourself and others to read your code much more easily in the future.  But at the end of the day, the most important thing is providing a robust and sound product to exchange with your users.  If you can&#8217;t do this, then why bother?&lt;/p&gt;


	&lt;p&gt;A great website on all the &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; tags is the &lt;a href=&quot;http://www.w3schools.com/&quot;&gt;w3 schools forums&lt;/a&gt;.  I highly recommend going through this site and reading up on every tag.  For example, did you know that all your efforts to try and style that submit button would be handled by using a &lt;a href=&quot;http://particletree.com/features/rediscovering-the-button-element/&quot;&gt;button tag&lt;/a&gt;, or that select boxes are not that hard to do by hand when you have to?&lt;/p&gt;


	&lt;p&gt;Also, you need to get a grip about how &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; works. Understanding what the differences between a &lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt; request, and why would you use each in what scenario is critical to understanding how your rails app works and really throws you if you try to learn anything about RESTful interfaces.&lt;/p&gt;


	&lt;p&gt;In a nutshell (ignorning anything about &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; for now that just builds on top of this), there are two ways most browsers will accept a form sent to them from a web browser.  They are called &lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt;.  You use &lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; when you are retrieving something from a application and are not trying to make any changes.  You use &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt; when you are submitting some data to make changes.  So a query form (asking the application about something) would usually be a &lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; request and creating a new user (sending data to the application) would be a &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt; request.&lt;/p&gt;


	&lt;p&gt;If you don&#8217;t get this, then trying to understand why a &lt;span class=&quot;caps&quot;&gt;CREATE&lt;/span&gt; action uses a &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt; and a &lt;span class=&quot;caps&quot;&gt;SHOW&lt;/span&gt; action uses &lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; would be unintuitive.  But with the above single paragraph it becomes quite clear.  (I&#8217;ll go into RESTful methods in a later post).  Here is a good write up about &lt;a href=&quot;http://www.cs.tut.fi/~jkorpela/forms/methods.html&quot;&gt;&lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt;&lt;/a&gt;.  Just one point, it clears up the word &#8216;idempotent&#8217; about 8 paragraphs in (it basically means, &#8220;doesn&#8217;t make any change on the server&#8221;).&lt;/p&gt;


	&lt;p&gt;As for &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;, that is what your Apache Web Server, Mongrel server or mod-rails application are handling.  This is the give and take between browsers and their servers.  It would do you well to understand how this works.&lt;/p&gt;


	&lt;p&gt;The bottom line is the &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; and the &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; you and I use &lt;span class=&quot;caps&quot;&gt;ALL DAY&lt;/span&gt; to get our Rails sites up and running is important and a foundation to understanding everything else in Ruby on Rails.  Honestly, if you don&#8217;t get &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;, you will &lt;span class=&quot;caps&quot;&gt;NOT&lt;/span&gt; get Rails, you might be able to punch out a website only using helpers, and if you can, good on you, but if something breaks at 2am and you have to fix it, I am sure you will wish you spent a few hours looking over how that form tag really works.&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-19:311</id>
    <published>2008-04-19T23:57:00Z</published>
    <updated>2008-04-20T00:09:18Z</updated>
    <link href="http://lindsaar.net/2008/4/19/bloggers-unite" rel="alternate" type="text/html"/>
    <title>Bloggers Unite</title>
<summary type="html">&lt;p&gt;&lt;img src=&quot;http://blogcatalog.s3.amazonaws.com/badge/080515/humanrightsbadge3.jpg&quot; /&gt; 
This year on May 15th there is going to be a world wide bloggers unite on the subject of Human Rights.&lt;/p&gt;


	&lt;p&gt;This is a great opportunity to raise public awareness on the subject of Human Rights.  We all have them, but in the modern world of pending global governments (which I think are just another way to remove power from the people) It is time for all of us to become away of what it means to be living on this planet, what it means to be a member of this society, what it means to have a family and what it means to just be you.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;&lt;img src=&quot;http://blogcatalog.s3.amazonaws.com/badge/080515/humanrightsbadge3.jpg&quot; /&gt; 
This year on May 15th there is going to be a world wide bloggers unite on the subject of Human Rights.&lt;/p&gt;


	&lt;p&gt;This is a great opportunity to raise public awareness on the subject of Human Rights.  We all have them, but in the modern world of pending global governments (which I think are just another way to remove power from the people) It is time for all of us to become away of what it means to be living on this planet, what it means to be a member of this society, what it means to have a family and what it means to just be you.&lt;/p&gt;
&lt;p&gt;If you are not sure what human rights actually are, you can view a bunch of short videos at the &lt;a href=&quot;http://www.youthforhumanrights.org/&quot;&gt;Youth for Human Rights&lt;/a&gt; and then go over to &lt;a href=&quot;http://www.amnesty.org/&quot;&gt;Amnesty International&lt;/a&gt; and check out their site to find out what all the fuss is about.&lt;/p&gt;


	&lt;p&gt;You can, of course, also join in and put up the &lt;a href=&quot;http://unite.blogcatalog.com/&quot;&gt;bloggers unite human rights badge&lt;/a&gt; on your site and blog about it on May 15th.&lt;/p&gt;


	&lt;p&gt;You may or may not know that there are 30 basic human rights which are laid out in the &lt;a href=&quot;http://www.humanrights.org.au/declaration-human-rights.htm&quot;&gt;Universal Declaration of Human Rights.&lt;/a&gt;  There is also a plain english (simplified) &lt;a href=&quot;http://www0.un.org/cyberschoolbus/humanrights/resources/plain.asp&quot;&gt;version&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Have a read, they are quite surprising!&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-19:303</id>
    <published>2008-04-19T03:22:00Z</published>
    <updated>2008-04-18T03:24:30Z</updated>
    <category term="PostgreSQL"/>
    <category term="Ruby on Rails"/>
    <category term="Ruby on Rails Tips"/>
    <link href="http://lindsaar.net/2008/4/19/tip-11-transact-your-migrations" rel="alternate" type="text/html"/>
    <title>Tip #11 - Transact Your Migrations!</title>
<summary type="html">&lt;p&gt;If you are using Rails, you are most likely using migrations. Have you ever had a migration fail half way through?  Have you ever then had to figure out how to find each change and revert it in the database?  Would you like to &lt;strong&gt;never&lt;/strong&gt; have to do that again?  Here is how&#8230;&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;If you are using Rails, you are most likely using migrations. Have you ever had a migration fail half way through?  Have you ever then had to figure out how to find each change and revert it in the database?  Would you like to &lt;strong&gt;never&lt;/strong&gt; have to do that again?  Here is how&#8230;&lt;/p&gt;
&lt;h4&gt;&lt;span class=&quot;caps&quot;&gt;USE TRANSACTIONS&lt;/span&gt;&lt;/h4&gt;


	&lt;p&gt;I sometimes wonder why this just isn&#8217;t the default.  When I am doing a migration, I either want the thing to work completely &lt;strong&gt;all&lt;/strong&gt; the way through, or I want &lt;strong&gt;nothing&lt;/strong&gt; done to the database.&lt;/p&gt;


	&lt;p&gt;Luckily, you can do this with transactions.&lt;/p&gt;


	&lt;p&gt;A transaction (for those non &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; people out there) is an idea of a series of events being atomic.  That is, either, they all are executed without error, or if any one of them fails or faults, then no change is made to the database at all.&lt;/p&gt;


	&lt;p&gt;Luckily, adding transactions to a migration is very easy.&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;ComplexMigrationThatCanNotFail&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Migration&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.up&lt;tt&gt;
&lt;/tt&gt;    transaction &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      add_column &lt;span class=&quot;sy&quot;&gt;:table&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:name&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:type&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      add_column &lt;span class=&quot;sy&quot;&gt;:table&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:name&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:type&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;c&quot;&gt;# Complex task #1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      remove_column &lt;span class=&quot;sy&quot;&gt;:table&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:name&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:type&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      remove_column &lt;span class=&quot;sy&quot;&gt;:table&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:name&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:type&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;c&quot;&gt;# Complex task #2&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.down&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;c&quot;&gt;# ... Down script&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Now, say your migration fails at the second remove column, no fear, everything is rolled back to the start point, you can read the rake error messages, fix the problem, and try again.&lt;/p&gt;


	&lt;p&gt;Of course, you are testing this on the development server, so no major harm done if it blows up a couple of times, but I don&#8217;t know about you, but I have lots more things to do than try to restore two gigabytes of staging or development database :)&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-18:302</id>
    <published>2008-04-18T00:42:00Z</published>
    <updated>2008-04-21T00:45:18Z</updated>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <category term="Ruby on Rails Tips"/>
    <link href="http://lindsaar.net/2008/4/18/tip-10-the-ruby-language" rel="alternate" type="text/html"/>
    <title>Tip #10 - The Ruby Language</title>
<summary type="html">&lt;p&gt;Learning Rails is hard enough without also facing the task of learning Ruby at the same time.  Here I go over some of the must knows in Ruby so that you get some basic understanding of how to do Rails.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Learning Rails is hard enough without also facing the task of learning Ruby at the same time.  Here I go over some of the must knows in Ruby so that you get some basic understanding of how to do Rails.&lt;/p&gt;
&lt;p&gt;This is part of my 8-Part tip-a-thon on the &lt;a href=&quot;http://www.lindsaar.net/2008/4/17/tip-8-how-learn-ruby-on-rails&quot;&gt;Must Know Facets of Ruby on Rails&lt;/a&gt;.  If you haven&#8217;t already, please read the first part and then come forward (there is a link at the bottom of each article that links to the next)&lt;/p&gt;


	&lt;h4&gt;Learning Ruby&lt;/h4&gt;


	&lt;p&gt;&lt;strong&gt;Ruby is fun.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;You have probably heard that, you have also probably heard that Rails is fun.  Both are true.&lt;/p&gt;


	&lt;p&gt;But there is nothing fun about tearing your hair out online trying to figure out why a piece of code doesn&#8217;t work, especially if you can&#8217;t even read the code!&lt;/p&gt;


	&lt;p&gt;So Learning Ruby is probably &lt;em&gt;the&lt;/em&gt; most important step to becomming a Ruby on Rails developer.&lt;/p&gt;


	&lt;p&gt;But how do you do that?&lt;/p&gt;


	&lt;p&gt;Well, this is how I did it.&lt;/p&gt;


	&lt;h5&gt;Read&#8230; &amp;mdash; &lt;span class=&quot;caps&quot;&gt;LOTS&lt;/span&gt;&lt;/h5&gt;


	&lt;p&gt;If you don&#8217;t already own the &lt;a href=&quot;http://pragprog.com/titles/ruby&quot;&gt;Pickaxe&lt;/a&gt;, then you should go and get it.  If you are just looking to see if Ruby is for you, then maybe you could read the online edition of &lt;a href=&quot;http://www.rubycentral.com/pickaxe/&quot;&gt;Version 1 of the Pickaxe&lt;/a&gt;.  It is older, but contains enough information and is current enough to be worthwhile.  Ruby hasn&#8217;t changed &lt;em&gt;that&lt;/em&gt; much since the version 1 and all the basic concepts are the same.&lt;/p&gt;


	&lt;p&gt;You can read through _why&#8217;s (who is basically Ruby&#8217;s mad scientist) &lt;a href=&quot;http://poignantguide.net/&quot;&gt;Poignant Guide to Ruby&lt;/a&gt; on learning Ruby.  I must admit, I tried, I did&#8230; but it lost me about the time the Fox/Dog/Crazy thin dude lost is truck and someone had stolen it&#8230; you&#8217;ll need to have a look and read to see what I mean :)&lt;/p&gt;


	&lt;p&gt;There are many other fine Ruby books out there as well.  I can also recommend the O&#8217;Rielly book, mainly because it has a different approach to the Pickaxe and gives you a different view of the same problem.&lt;/p&gt;


	&lt;p&gt;If you read through these books, and do the examples (the Pickaxe is good for this as you build a Jukebox as you go!) you will get some good basic understandings about how Ruby ticks.&lt;/p&gt;


	&lt;h5&gt;Use Ruby Everywhere you Can&lt;/h5&gt;


	&lt;p&gt;This is a key one.  When you are first learning Ruby, and you need to do something outside of Rails that could use a bit of shell scripting or some basic programming, use Ruby!&lt;/p&gt;


	&lt;p&gt;There is pretty much no task that Ruby can&#8217;t handle.  I have used it to parse incomming emails, used it to merge &lt;span class=&quot;caps&quot;&gt;CSV&lt;/span&gt; files together and also used it to clean up bad code points in a supposed unicode file.&lt;/p&gt;


	&lt;p&gt;I have even used it to help handle someone attacking one of our servers.&lt;/p&gt;


	&lt;p&gt;Once you decide you can use Ruby, go for it and learn all the little tricks inside of that big box called the standard library.  There is so much in there that you can use and you will be surprised at how many tools you have at your disposal.&lt;/p&gt;


	&lt;h5&gt;Practice with a different paradigm&lt;/h5&gt;


	&lt;p&gt;Ruby on Rails is one use for Ruby and a very exact use.  But following on from the previous point, try Ruby in different paradigms.&lt;/p&gt;


	&lt;p&gt;What do I mean?  Well, make a server in Ruby that serves messages of any type over a network stack.  Make a program that searches your hard drive for files, make something that plays some music.  Really, anything.&lt;/p&gt;


	&lt;p&gt;When I did this I found that my understand of how Ruby on Rails works expanded a huge amount.  Rails is just one medium sized Ruby program that handles routing, talks to your database and allows you to serve up web pages.  Once you know how all the Ruby stuff fits together, you will understand Rails a lot more.&lt;/p&gt;


	&lt;h5&gt;Next Up&lt;/h5&gt;


	&lt;p&gt;Next in the series is the &lt;a href=&quot;http://lindsaar.net/2008/4/21/tip-12-html-and-http-are-your-friends&quot;&gt;&lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; are Your Friends&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-17:299</id>
    <published>2008-04-17T13:17:00Z</published>
    <updated>2008-04-17T13:20:02Z</updated>
    <link href="http://lindsaar.net/2008/4/17/apple-release-the-apple-1-upgradable-to-32k-when-available" rel="alternate" type="text/html"/>
    <title>Apple Release the APPLE-1 - Upgradable to 32k (When Available)</title>
<summary type="html">&lt;p&gt;I know it is a bit late, and all the other cooler technology blogs have already covered this&#8230;&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;I know it is a bit late, and all the other cooler technology blogs have already covered this&#8230;&lt;/p&gt;
&lt;p&gt;But I just couldn&#8217;t resist.  It is such a great computer, and only $666.66 it is a true &lt;span class=&quot;caps&quot;&gt;BARGIN&lt;/span&gt;!&lt;/p&gt;


	&lt;p&gt;Check it out!&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://lindsaar.net/assets/2008/4/17/apple_i.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-17:298</id>
    <published>2008-04-17T12:11:00Z</published>
    <updated>2008-04-18T00:45:16Z</updated>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <category term="Ruby on Rails Tips"/>
    <link href="http://lindsaar.net/2008/4/17/tip-9-learn-programming-theory" rel="alternate" type="text/html"/>
    <title>Tip #9 - Learn Programming Theory</title>
<summary type="html">&lt;p&gt;Being a Rails developer means that, yes, you too need to learn how to (&lt;strong&gt;gasp&lt;/strong&gt;) program!  No, seriously!  Here are my tips on that subject.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Being a Rails developer means that, yes, you too need to learn how to (&lt;strong&gt;gasp&lt;/strong&gt;) program!  No, seriously!  Here are my tips on that subject.&lt;/p&gt;
&lt;p&gt;This is part of my 8-Part tip-a-thon on the &lt;a href=&quot;http://www.lindsaar.net/2008/4/17/tip-8-how-learn-ruby-on-rails&quot;&gt;Must Know Facets of Ruby on Rails&lt;/a&gt;.  If you haven&#8217;t already, please read the first part and then come forward (there is a link at the bottom of the previous link to this article)&lt;/p&gt;


	&lt;p&gt;Learning how to Program is an interesting one. Where on Earth do you find a definitive guide on how to program?&lt;/p&gt;


	&lt;p&gt;I can tell you what &lt;em&gt;not&lt;/em&gt; to do here, don&#8217;t go out and buy the latest &#8220;Learn Ruby on Rails in 24 Hours&#8221; book, or &#8220;Ruby on Rails for Dummies&#8221;, if and when such a beast surfaces. No.  Actually, I am not even talking about Ruby, Java, C or any other language, what I am talking about is Learning to Program a computer.&lt;/p&gt;


	&lt;p&gt;A computer teacher of mine once said &#8220;A computer will &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;ALWAYS&lt;/span&gt;&lt;/em&gt; do what you tell it to do.  Not only what you &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;WANT&lt;/span&gt;&lt;/strong&gt; it to do.&#8221;.  I have kept this as a stable learning datum ever since.  When I find a program is not working the way I would expect, I will go through the code, line by line inspecting it until I find where I &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;TOLD&lt;/span&gt;&lt;/strong&gt; it to do something I didn&#8217;t &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;WANT&lt;/span&gt;&lt;/strong&gt; it to do.&lt;/p&gt;


	&lt;p&gt;If you don&#8217;t find the idea of pouring through code for hours to find that one bug interesting or exciting, then programming may not be your thing and you might find more fun somewhere else.&lt;/p&gt;


	&lt;p&gt;But for the rest of us, this is where we want to be.&lt;/p&gt;


	&lt;p&gt;You know, probably the best write up of this I have found is called &lt;a href=&quot;http://norvig.com/21-days.html&quot;&gt;Teach Yourself Programming in 10 Years&lt;/a&gt; and it is a great read with a lot of good advice.  I recommend you go and read this now and see what areas you can clean up and improve on.&lt;/p&gt;


	&lt;p&gt;If you are a complete beginner to programming, don&#8217;t fear, the way to mastery is by taking small and deliberate steps.&lt;/p&gt;


	&lt;p&gt;I would recommend you go and read Chris Pine&#8217;s fantastic &#8220;Learn to Program:http://pine.fm/LearnToProgram/ book.  The first edition is on the website for free and is very good.  You can get later editions from the store from his site.&lt;/p&gt;


	&lt;p&gt;Where to go from there? Well, for starters, you should subscribe to the &lt;a href=&quot;http://www2.ruby-lang.org/en/20020104.html&quot;&gt;Ruby Talk&lt;/a&gt; mailing list at least, maybe even Ruby Core. You should read through some of the posts from the more experienced Ruby Programmers as they come up and watch with interest when someone says &#8220;How do I solve &lt;span class=&quot;caps&quot;&gt;XYZ&lt;/span&gt;?&#8221; and see the answers, test the answers and see if you could do better (you might surprise yourself).&lt;/p&gt;


	&lt;p&gt;Also, if you do see an answer from one of the Ruby Gurus, don&#8217;t be afraid to ask how it works if you don&#8217;t understand it.  The Ruby Community is one of the friendliest communities I have met, and they are always willing to explain their methodologies or ways of answering a problem.&lt;/p&gt;


	&lt;p&gt;Finally, go look at the &lt;a href=&quot;http://www.rubyquiz.com/&quot;&gt;Ruby Quiz&lt;/a&gt; Series done and hosted by James Edward Gray II.  It is a good exercise to sit down and actually try to do these quizzes in any order.  It teaches you a &lt;span class=&quot;caps&quot;&gt;LOT&lt;/span&gt; about programming.  Just like an elite Athlete needs to train in all sorts of exercises to be competent at their core devotion, so to do you need to exercise your programming mental powers to think about problems differently or to expand your ideas and ability to think.&lt;/p&gt;


	&lt;p&gt;Next step, &lt;a href=&quot;http://lindsaar.net/2008/4/18/tip-10-the-ruby-language&quot;&gt;The Ruby Language&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-17:297</id>
    <published>2008-04-17T12:10:00Z</published>
    <updated>2008-04-17T12:12:11Z</updated>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <category term="Ruby on Rails Tips"/>
    <link href="http://lindsaar.net/2008/4/17/tip-8-how-learn-ruby-on-rails" rel="alternate" type="text/html"/>
    <title>Tip #8 - Must Know Facets of Ruby on Rails</title>
<summary type="html">&lt;p&gt;Sometimes it is easy to forget that when you take the plunge to learn something as encompassing as ruby on Rails, you forget just how &lt;span class=&quot;caps&quot;&gt;MUCH&lt;/span&gt; you need to learn, and it can all seem a bit overwhelming at first.  Here is a good way to go about learning it.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Sometimes it is easy to forget that when you take the plunge to learn something as encompassing as ruby on Rails, you forget just how &lt;span class=&quot;caps&quot;&gt;MUCH&lt;/span&gt; you need to learn, and it can all seem a bit overwhelming at first.  Here is a good way to go about learning it.&lt;/p&gt;
&lt;p&gt;This might seem obvious, but one of the hardest things to get is that you are not just learning a programming Language with Ruby on Rails, you are learning (or trying to learn) a full stack web development Framework.&lt;/p&gt;


	&lt;p&gt;Now, just have a think about what that means.  Ok.  What does Full Stack imply here?  Well, for starters, it means that you need to know something about all of the following to get anything meaningful done in Ruby on Rails:&lt;/p&gt;


	&lt;h5&gt;Must Know&lt;/h5&gt;


	&lt;ol&gt;
	&lt;li&gt;Programming Theory&lt;/li&gt;
		&lt;li&gt;The Ruby Language&lt;/li&gt;
		&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; Tags &#38; Design&lt;/li&gt;
		&lt;li&gt;Cascading Style Sheets&lt;/li&gt;
		&lt;li&gt;Database Theory &#38; Design&lt;/li&gt;
		&lt;li&gt;Javascript &#38; &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;At least one of the three database server implementations&lt;/li&gt;
		&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; or &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h5&gt;Will Need To Know&lt;/h5&gt;


	&lt;ol&gt;
	&lt;li&gt;Version Control&lt;/li&gt;
		&lt;li&gt;Representative State Transfer (REST)&lt;/li&gt;
		&lt;li&gt;Unix (or another Server Technology)&lt;/li&gt;
		&lt;li&gt;Web Serving&lt;/li&gt;
		&lt;li&gt;EMail and EMail servers&lt;/li&gt;
		&lt;li&gt;Domain Name Systems (sometimes)&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Now, if you don&#8217;t have a basic understand of the first 8 layers above, honestly, you will have a &lt;span class=&quot;caps&quot;&gt;HARD&lt;/span&gt; time getting your head around Ruby on Rails.  Seriously, it will make you feel spinny and frustrated that you can&#8217;t get the darn thing to work.&lt;/p&gt;


	&lt;p&gt;The 6 that follow are optional, depending on what type of application you are developing.  Some will argue that &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; are an absolute requirement, and to be fair, to make a real application, they are.  But they also are not part of what you &lt;span class=&quot;caps&quot;&gt;MUST&lt;/span&gt; know to get something working and they fall under the programming theory and design as a methodology.&lt;/p&gt;


	&lt;p&gt;There are of course many other technologies that you &lt;span class=&quot;caps&quot;&gt;CAN&lt;/span&gt; use in a Rails app, but the above are, I think, the core minimum to get started.&lt;/p&gt;


	&lt;p&gt;Now, what do I mean by &#8220;Make sure you understand what you are doing&#8221; ?  Well, what I mean is that if you have decided to learn Rails, sure, go ahead and make the 10 minute blog or todo list, or even go get the Peepcode on starting &lt;a href=&quot;http://peepcode.com/products/rails-from-scratch-part-i&quot;&gt;Rails from Scratch&lt;/a&gt; (very good by the way), but once you have whetted your appetite, come back to that list of the Must Know 8 and start at the top.&lt;/p&gt;


	&lt;p&gt;The other trick here is, if you find something in a tutorial that you don&#8217;t understand, spend the time to go and find out about it and why it works and how it works.  Getting these underlying understandings will build a strong foundation for you to expand your knowledge overall.&lt;/p&gt;


	&lt;p&gt;I am going to do a series of posts that walk through the top 8 layers above.  The first one I have already posted and it is called &lt;a href=&quot;http://www.lindsaar.net/2008/4/17/tip-9-learn-programming-theory&quot;&gt;Learn Programming Theory&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-16:278</id>
    <published>2008-04-16T22:12:00Z</published>
    <updated>2008-04-16T05:14:23Z</updated>
    <category term="Ruby on Rails"/>
    <category term="Ruby on Rails Tips"/>
    <link href="http://lindsaar.net/2008/4/16/tip-7-shell-shortcuts-you-should-know-and-love" rel="alternate" type="text/html"/>
    <title>Tip #7 - Shell Shortcuts You Should Know and Love</title>
<summary type="html">&lt;p&gt;Face it, you use Ruby, you use Rails, you are going to use the shell, either in the console or directly, here are some shortcuts I can&#8217;t live without.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Face it, you use Ruby, you use Rails, you are going to use the shell, either in the console or directly, here are some shortcuts I can&#8217;t live without.&lt;/p&gt;
&lt;p&gt;Have you ever done this?&lt;/p&gt;


&lt;pre class=&quot;shell&quot;&gt;
baci:~/rails_app mikel$ ./script/generate user first_name:string
mid_name:string last_name:string address1:string address2:string
address3:string suburb:string state:string country:string
post_code:string home_phone:string work_phone:string mobile_phone:string
email:string

Couldn't find 'users' generator
baci:~/rails_app mikel$ 
&lt;/pre&gt;

	&lt;p&gt;Grr&#8230; of course, you forgot to put the word &#8220;model&#8221; before the word &#8220;user&#8221;.&lt;/p&gt;


	&lt;p&gt;You can hit the up arrow and get all the text back, but if you were like me, you used to hit the left arrow and hold it down for about half an hour to get to the start of the line.  Well, no more.  Shell Shortcuts are your friend!&lt;/p&gt;


	&lt;p&gt;Simply type up arrow and then &#8220;&lt;strong&gt;Ctrl-A&lt;/strong&gt;&#8221; and you are at the start of the line.&lt;/p&gt;


	&lt;p&gt;Hit &#8220;&lt;strong&gt;Ctrl-E&lt;/strong&gt;&#8221; and you will be at the end of the line.&lt;/p&gt;


	&lt;p&gt;Or, if you want a clean screen, &#8220;&lt;strong&gt;Ctrl-L&lt;/strong&gt;&#8221; will do it for you.&lt;/p&gt;


	&lt;p&gt;If you make a mistake, &#8220;&lt;strong&gt;Ctrl-_&lt;/strong&gt;&#8221; will undo it.&lt;/p&gt;


	&lt;p&gt;And you also have cut and paste on the command line.&lt;/p&gt;


	&lt;p&gt;&#8220;&lt;strong&gt;Ctrl-U&lt;/strong&gt;&#8221; cuts the beginning of the line to the cursor&lt;/p&gt;


	&lt;p&gt;&#8220;&lt;strong&gt;Ctrl-K&lt;/strong&gt;&#8221; cuts from the cursor to the end of the line&lt;/p&gt;


	&lt;p&gt;and &#8220;&lt;strong&gt;Ctrl-Y&lt;/strong&gt;&#8221; pastes whatever you have cut out back into the screen at the cursor.&lt;/p&gt;


	&lt;p&gt;The cool thing is, all of these work within the Rails console as well!.&lt;/p&gt;


	&lt;p&gt;So, you are in the console and type:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&amp;gt;&amp;gt; &lt;span class=&quot;co&quot;&gt;User&lt;/span&gt;.find(&lt;span class=&quot;sy&quot;&gt;:all&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:conditions&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;user_name = ? AND first_name = ?&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;                                   &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mikel&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Mikel&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;])&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;And forget that you want to assign it to the &#8220;user&#8221; variable?  Well, type &#8220;&lt;strong&gt;Ctrl-A&lt;/strong&gt;&#8221; and then &#8220;*user = *&#8221; and hit return and you are done.&lt;/p&gt;


	&lt;p&gt;Nice, handy time saving short cuts.&lt;/p&gt;


	&lt;p&gt;You can also find out other ones by Googling &lt;a href=&quot;http://www.google.com/search?&amp;amp;rls=en&amp;amp;q=Bash+shell+short+cuts&amp;amp;ie=UTF-8&amp;amp;oe=UTF-8&quot;&gt;Bash shell short cuts&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Of course, the above assumes you are using Bash, Ksh or other SH like shells on Mac or *nix&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-16:277</id>
    <published>2008-04-16T03:16:00Z</published>
    <updated>2008-04-16T03:20:45Z</updated>
    <category term="PostgreSQL"/>
    <link href="http://lindsaar.net/2008/4/16/postgresql-on-windows-startup-errors" rel="alternate" type="text/html"/>
    <title>PostgreSQL on Windows - Startup Errors</title>
<summary type="html">&lt;p&gt;If you are using PostgreSQL on Windows and you get:  &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;FATAL&lt;/span&gt;: pre-existing shared memory block is still in use&lt;/strong&gt; Or you get: &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;HINT&lt;/span&gt;: Check if there are any old server processes still running, and terminate them.&lt;/strong&gt; errors, here is how you fix it.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;If you are using PostgreSQL on Windows and you get:  &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;FATAL&lt;/span&gt;: pre-existing shared memory block is still in use&lt;/strong&gt; Or you get: &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;HINT&lt;/span&gt;: Check if there are any old server processes still running, and terminate them.&lt;/strong&gt; errors, here is how you fix it.&lt;/p&gt;
&lt;p&gt;What has happened is your postgres server has crashed some how, or failed to start, and now it can&#8217;t start again at all.&lt;/p&gt;


	&lt;p&gt;But you look through your task manager, and nothing is there that looks like postgres.&lt;/p&gt;


	&lt;p&gt;Well, look again, you will probably find a &#8220;drwatson&#8221; process running, owned by the postgres service account user.&lt;/p&gt;


	&lt;p&gt;Kill this task, and all will be good again.&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-15:264</id>
    <published>2008-04-15T23:02:00Z</published>
    <updated>2008-04-16T00:13:43Z</updated>
    <category term="Ruby on Rails"/>
    <category term="Ruby on Rails Tips"/>
    <category term="TMail"/>
    <link href="http://lindsaar.net/2008/4/15/tip-6-validating-the-domain-of-an-email-address-with-ruby-on-rails" rel="alternate" type="text/html"/>
    <title>Tip #6 - Validating the Domain of an Email Address with Ruby on Rails</title>
<summary type="html">&lt;p&gt;So, in the last two tips, I have shown how to check the format of the email and save the actual address only in the database.  But how to check that the email domain name is valid?  Easy!&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;So, in the last two tips, I have shown how to check the format of the email and save the actual address only in the database.  But how to check that the email domain name is valid?  Easy!&lt;/p&gt;
&lt;p&gt;When you are getting an email address from a user, sometimes it might not matter that it is not a real address (like on this blog, I don&#8217;t check).&lt;/p&gt;


	&lt;p&gt;But if you are creating an account, yeah, it matters, you want to know that the address is for the right person.&lt;/p&gt;


	&lt;p&gt;Now, the only way you can really do this is by sending them a confirmation email that they have to reply to.  But, when the user is filling out the form, we should do everything we can, then and there to make sure that the address is correct, especially since we don&#8217;t want them sitting, waiting at their inbox for the email that will never come!&lt;/p&gt;


	&lt;p&gt;Luckily again, using TMail and a bit of built in ruby goodness, we can do something about it.&lt;/p&gt;


	&lt;p&gt;What we need to do in a nutshell, is take the email address, split off the domain, look up the domain, find any mail exchanger records for that domain and then if all of that passes, accept the email address as probably valid.&lt;/p&gt;


	&lt;p&gt;If any of those steps fail though, we know that the domain name is either an incorrect one, or misspelt somehow.&lt;/p&gt;


	&lt;p&gt;Anyway, enough talk, lets see the code.&lt;/p&gt;


	&lt;p&gt;First we need to set up the validation, so I am going to assume you are using the email validation from &lt;a href=&quot;http://lindsaar.net/2008/4/14/tip-4-detecting-a-valid-email-address&quot;&gt;Tip #4&lt;/a&gt; and so I am just going to add to it:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;User&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  validate &lt;span class=&quot;sy&quot;&gt;:valid_email?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;valid_email?&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;begin&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      domain_name = &lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(email).domain&lt;tt&gt;
&lt;/tt&gt;      domain_valid?(domain_name)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;rescue&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      errors.add(&lt;span class=&quot;sy&quot;&gt;:email&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;has an invalid format.&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Now, what I have added is the &#8220;addr = TMail::Address.parse(email).domain&#8221;, what does this do?  Well, lets ask the console:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Mikel A. &amp;lt;spam@lindsaar.net&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).domain&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#=&amp;gt; &amp;quot;lindsaar.net&amp;quot;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;spam@ruby-lang.org&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).domain&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#=&amp;gt; &amp;quot;ruby-lang.org&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;As you can see, it parses the email, then finds the domain name and gives it back to you as a string, very handy!&lt;/p&gt;


	&lt;p&gt;So after I did that, I make a call to &#8220;domain_valid?(domain_name)&#8221;, now, unfortunately, this isn&#8217;t built into Ruby or Rails, but it is pretty simple to set up.  To do it, we need the resolv library that ships with Ruby, so, in your User class still, you can add the following method:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;User&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  require &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;resolv&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;domain_valid?&lt;/span&gt;(domain)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;co&quot;&gt;Resolv&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;DNS&lt;/span&gt;.open &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |dns|&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;iv&quot;&gt;@mx&lt;/span&gt; = dns.getresources(domain.to_s, &lt;span class=&quot;co&quot;&gt;Resolv&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;DNS&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Resource&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;IN&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;MX&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;iv&quot;&gt;@mx&lt;/span&gt;.empty?&lt;tt&gt;
&lt;/tt&gt;      errors_add(&lt;span class=&quot;sy&quot;&gt;:email&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;domain name can not be found.&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Now, this method is fairly neat.&lt;/p&gt;


	&lt;p&gt;What it does is load the resolve library, then it opens up the &lt;span class=&quot;caps&quot;&gt;DNS&lt;/span&gt; system, and gets all the MX records for the domain name you give it.  If there are MX records (which means there is a way for &lt;span class=&quot;caps&quot;&gt;SMTP&lt;/span&gt; servers to route email to the domain name recipient) then the instance variable @mx will be an array containing each MX record object.  So all we have to do is check to see if that is empty or not.  If it is, we know that there are no MX records and so we add an error to the object on the email attribute that tells the user that the domain name is invalid.&lt;/p&gt;


	&lt;p&gt;So, there you go.  Your user fills out the form, and you do a quick check on the domain name to see if the domain has an MX record as &lt;span class=&quot;caps&quot;&gt;WELL&lt;/span&gt; as checking that the address itself is valid.&lt;/p&gt;


	&lt;p&gt;Now the only way a user can enter a wrong address and you accept it, is if they enter a false address, but this, you will catch with your verification email, and besides, this type of user will not be waiting for their verification email anyway, so who cares?&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://lindsaar.net/">
    <author>
      <name>mikel</name>
    </author>
    <id>tag:lindsaar.net,2008-04-14:263</id>
    <published>2008-04-14T20:21:00Z</published>
    <updated>2008-04-15T03:40:20Z</updated>
    <category term="Ruby on Rails"/>
    <category term="Ruby on Rails Tips"/>
    <category term="TMail"/>
    <link href="http://lindsaar.net/2008/4/14/tip-5-cleaning-up-an-verifying-an-email-address-with-ruby-on-rails" rel="alternate" type="text/html"/>
    <title>Tip #5 - Cleaning Up an Email Address with Ruby on Rails</title>
<summary type="html">&lt;p&gt;So you have an email address field on a form in Rails, but how are you going to make sure that all those users enter a sane and well formatted email address?  Here is a simple fix to that problem.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;So you have an email address field on a form in Rails, but how are you going to make sure that all those users enter a sane and well formatted email address?  Here is a simple fix to that problem.&lt;/p&gt;
&lt;p&gt;If you read the &lt;a href=&quot;http://lindsaar.net/2008/4/14/tip-4-detecting-a-valid-email-address&quot;&gt;previous tip&lt;/a&gt; then you would have setup some basic validation of the format of your email address.&lt;/p&gt;


	&lt;p&gt;One thing I didn&#8217;t tell you here is that it will also clean up any address you give it.&lt;/p&gt;


	&lt;p&gt;To show you what I mean, lets try some basics in the console:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;spam@lindsaar.net&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#=&amp;gt; #&amp;lt;TMail::Address spam@lindsaar.net&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;spam@lindsaar.net&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).to_s&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#=&amp;gt; &amp;quot;spam@lindsaar.net&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;OK, no surprises there, we give tmail &#8216;spam@lindsaar.net&#8217; and it returns what we gave it.&lt;/p&gt;


	&lt;p&gt;But the magic comes when we enter some slightly wrong addresses.  What happens if the user accidently adds some spaces:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;spam @ lindsaar . net&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).to_s&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#=&amp;gt; &amp;quot;spam@lindsaar.net&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;No problem, TMail sees that it is a basic mistake (though a bit contrived) and handles it.&lt;/p&gt;


	&lt;p&gt;What else can it handle?  Well, lets see:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;quot;mikel&amp;quot; &amp;lt;spam@lindsaar.net&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).to_s&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#=&amp;gt; &amp;quot;mikel &amp;lt;spam@lindsaar.net&amp;gt;&amp;quot;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;lt;spam@lindsaar.net&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).to_s&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#=&amp;gt; &amp;quot;spam@lindsaar.net&amp;quot;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Mikel A. &amp;lt;spam@lindsaar.net&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).to_s&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#=&amp;gt; &amp;quot;\&amp;quot;Mikel A.\&amp;quot; &amp;lt;spam@lindsaar.net&amp;gt;&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;OK, the basics are covered.&lt;/p&gt;


	&lt;p&gt;But, what is nice is that you can choose just to save the email address itself in your database, without the phrase at the front (that is the bit that the owner of the address can put in quotes).  You can do this like so:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Mikel A. &amp;lt;spam@lindsaar.net&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).spec&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;spam@lindsaar.net&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;So in your model, you can make a write attribute filter on the &#8220;email&#8221; attribute of the class you are working on and do something like this:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;User&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;email=&lt;/span&gt;(address)&lt;tt&gt;
&lt;/tt&gt;    write_attribute(&lt;span class=&quot;sy&quot;&gt;:email&lt;/span&gt;, &lt;span class=&quot;co&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Address&lt;/span&gt;.parse(address).spec)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Which means the only thing saved in your model will be the actual email address in a known and standard format.&lt;/p&gt;


	&lt;p&gt;Now, the only problem with this is that when you send an email to your user, you want to put the phrase (the bit at the front with the name) back into the email, that way it shows up as more of a personalized email in their inbox.  To do this is quite easy, just whack this in your model (assuming you have a first_name and last_name attribute for your user model):&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;User&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;email&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    phrase = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;%(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;first_name&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;last_name&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    address = read_attribute(&lt;span class=&quot;sy&quot;&gt;:email&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;phrase&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;dl&quot;&gt;#{&lt;/span&gt;address&lt;span class=&quot;dl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Now you will always get &#8216;FirstName LastName &amp;lt;email@domain.com&amp;gt;&#8217; as the address whenever you ask for the email of the person.&lt;/p&gt;


	&lt;p&gt;Nice hey?&lt;/p&gt;


	&lt;p&gt;Next tip, validating the email address by domain before saving.&lt;/p&gt;


	&lt;p&gt;blogLater&lt;/p&gt;


	&lt;p&gt;Mikel&lt;/p&gt;
          </content>  </entry>
</feed>
