<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sikachu!&#039;s Blog &#187; Programming</title>
	<atom:link href="http://sikachu.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://sikachu.com</link>
	<description>I&#039;m a Ruby on Rails / jQuery web developer. Follow me at @sikachu</description>
	<lastBuildDate>Sat, 25 Dec 2010 15:13:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>My Devise custom routes</title>
		<link>http://sikachu.com/2010/12/my-devise-custom-routes/</link>
		<comments>http://sikachu.com/2010/12/my-devise-custom-routes/#comments</comments>
		<pubDate>Mon, 13 Dec 2010 15:40:42 +0000</pubDate>
		<dc:creator>Sikachu!</dc:creator>
				<category><![CDATA[My Idea]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Devise]]></category>
		<category><![CDATA[Rails 3]]></category>

		<guid isPermaLink="false">http://sikachu.com/?p=757</guid>
		<description><![CDATA[Since the release of Rails 3, I&#8217;ve been using Devise as my authentication gem. While it delivers everything I need, its default route doesn&#8217;t look really good when I have only one authentication scope, such as User. The default route when you&#8217;re using devise_for :users will look like this: new_user_session GET /users/sign_in(.:format) {:action=&#62;&#34;new&#34;, :controller=&#62;&#34;devise/sessions&#34;} user_session [...]]]></description>
			<content:encoded><![CDATA[<p>Since the release of Rails 3, I&#8217;ve been using <a href="http://github.com/plataformatec/devise" target="_blank">Devise</a> as my authentication gem. While it delivers everything I need, its default route doesn&#8217;t look really good when I have only one authentication scope, such as <code>User</code>. The default route when you&#8217;re using <code>devise_for :users</code> will look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">         new_user_session GET    /users/sign_in(.:format)          {:action=&gt;&quot;new&quot;, :controller=&gt;&quot;devise/sessions&quot;}
             user_session POST   /users/sign_in(.:format)          {:action=&gt;&quot;create&quot;, :controller=&gt;&quot;devise/sessions&quot;}
     destroy_user_session GET    /users/sign_out(.:format)         {:action=&gt;&quot;destroy&quot;, :controller=&gt;&quot;devise/sessions&quot;}
            user_password POST   /users/password(.:format)         {:action=&gt;&quot;create&quot;, :controller=&gt;&quot;devise/passwords&quot;}
        new_user_password GET    /users/password/new(.:format)     {:action=&gt;&quot;new&quot;, :controller=&gt;&quot;devise/passwords&quot;}
       edit_user_password GET    /users/password/edit(.:format)    {:action=&gt;&quot;edit&quot;, :controller=&gt;&quot;devise/passwords&quot;}
                          PUT    /users/password(.:format)         {:action=&gt;&quot;update&quot;, :controller=&gt;&quot;devise/passwords&quot;}
 cancel_user_registration GET    /users/cancel(.:format)           {:action=&gt;&quot;cancel&quot;, :controller=&gt;&quot;devise/registrations&quot;}
        user_registration POST   /users(.:format)                  {:action=&gt;&quot;create&quot;, :controller=&gt;&quot;devise/registrations&quot;}
    new_user_registration GET    /users/sign_up(.:format)          {:action=&gt;&quot;new&quot;, :controller=&gt;&quot;devise/registrations&quot;}
   edit_user_registration GET    /users/edit(.:format)             {:action=&gt;&quot;edit&quot;, :controller=&gt;&quot;devise/registrations&quot;}
                          PUT    /users(.:format)                  {:action=&gt;&quot;update&quot;, :controller=&gt;&quot;devise/registrations&quot;}
                          DELETE /users(.:format)                  {:action=&gt;&quot;destroy&quot;, :controller=&gt;&quot;devise/registrations&quot;}
        user_confirmation POST   /users/confirmation(.:format)     {:action=&gt;&quot;create&quot;, :controller=&gt;&quot;devise/confirmations&quot;}
    new_user_confirmation GET    /users/confirmation/new(.:format) {:action=&gt;&quot;new&quot;, :controller=&gt;&quot;devise/confirmations&quot;}
                          GET    /users/confirmation(.:format)     {:action=&gt;&quot;show&quot;, :controller=&gt;&quot;devise/confirmations&quot;}</pre></div></div>

<p>As you can see, all of the routes are defined under <code>/users</code> path. So, I&#8217;ve modified my devise route block to this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">devise_for <span style="color:#ff3333; font-weight:bold;">:users</span>, <span style="color:#ff3333; font-weight:bold;">:skip</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:registrations</span>, <span style="color:#ff3333; font-weight:bold;">:sessions</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#008000; font-style:italic;"># devise/registrations</span>
  get <span style="color:#996600;">'signup'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'devise/registrations#new'</span>, <span style="color:#ff3333; font-weight:bold;">:as</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:new_user_registration</span>
  post <span style="color:#996600;">'signup'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'devise/registrations#create'</span>, <span style="color:#ff3333; font-weight:bold;">:as</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:user_registration</span>
  get <span style="color:#996600;">'users/cancel'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'devise/registrations#cancel'</span>, <span style="color:#ff3333; font-weight:bold;">:as</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:cancel_user_registration</span>
  get <span style="color:#996600;">'users/edit'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'devise/registrations#edit'</span>, <span style="color:#ff3333; font-weight:bold;">:as</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:edit_user_registration</span>
  put <span style="color:#996600;">'users'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'devise/registrations#update'</span>
  delete <span style="color:#996600;">'users/cancel'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'devise/registrations#destroy'</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># devise/sessions</span>
  get <span style="color:#996600;">'signin'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'devise/sessions#new'</span>, <span style="color:#ff3333; font-weight:bold;">:as</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:new_user_session</span>
  post <span style="color:#996600;">'signin'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'devise/sessions#create'</span>, <span style="color:#ff3333; font-weight:bold;">:as</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:user_session</span>
  get <span style="color:#996600;">'signout'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'devise/sessions#destroy'</span>, <span style="color:#ff3333; font-weight:bold;">:as</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:destroy_user_session</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Which will yield these routes:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family:monospace;">    new_user_registration GET    /signup(.:format)                 {:action=&gt;&quot;new&quot;, :controller=&gt;&quot;devise/registrations&quot;}
        user_registration POST   /signup(.:format)                 {:action=&gt;&quot;create&quot;, :controller=&gt;&quot;devise/registrations&quot;}
 cancel_user_registration GET    /users/cancel(.:format)           {:controller=&gt;&quot;devise/registrations&quot;, :action=&gt;&quot;cancel&quot;}
   edit_user_registration GET    /users/edit(.:format)             {:controller=&gt;&quot;devise/registrations&quot;, :action=&gt;&quot;edit&quot;}
                    users PUT    /users(.:format)                  {:action=&gt;&quot;update&quot;, :controller=&gt;&quot;devise/registrations&quot;}
             users_cancel DELETE /users/cancel(.:format)           {:controller=&gt;&quot;devise/registrations&quot;, :action=&gt;&quot;destroy&quot;}
         new_user_session GET    /signin(.:format)                 {:action=&gt;&quot;new&quot;, :controller=&gt;&quot;devise/sessions&quot;}
             user_session POST   /signin(.:format)                 {:action=&gt;&quot;create&quot;, :controller=&gt;&quot;devise/sessions&quot;}
     destroy_user_session GET    /signout(.:format)                {:action=&gt;&quot;destroy&quot;, :controller=&gt;&quot;devise/sessions&quot;}
            user_password POST   /users/password(.:format)         {:action=&gt;&quot;create&quot;, :controller=&gt;&quot;devise/passwords&quot;}
        new_user_password GET    /users/password/new(.:format)     {:action=&gt;&quot;new&quot;, :controller=&gt;&quot;devise/passwords&quot;}
       edit_user_password GET    /users/password/edit(.:format)    {:action=&gt;&quot;edit&quot;, :controller=&gt;&quot;devise/passwords&quot;}
                          PUT    /users/password(.:format)         {:action=&gt;&quot;update&quot;, :controller=&gt;&quot;devise/passwords&quot;}
        user_confirmation POST   /users/confirmation(.:format)     {:action=&gt;&quot;create&quot;, :controller=&gt;&quot;devise/confirmations&quot;}
    new_user_confirmation GET    /users/confirmation/new(.:format) {:action=&gt;&quot;new&quot;, :controller=&gt;&quot;devise/confirmations&quot;}
                          GET    /users/confirmation(.:format)     {:action=&gt;&quot;show&quot;, :controller=&gt;&quot;devise/confirmations&quot;}</pre></div></div>

<p>I think my new routes is much better. For example, I think user would prefer a path to sign in page to be <code>/signin</code> than <code>/users/sign_in</code>, as it more memorable.</p>
<p>I hope this post would inspire you more about customize Devise&#8217;s routes to fit your need.</p>
]]></content:encoded>
			<wfw:commentRss>http://sikachu.com/2010/12/my-devise-custom-routes/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>`method_missing` call stack in Ruby</title>
		<link>http://sikachu.com/2010/11/method-missing-call-stack-in-ruby/</link>
		<comments>http://sikachu.com/2010/11/method-missing-call-stack-in-ruby/#comments</comments>
		<pubDate>Tue, 23 Nov 2010 05:56:52 +0000</pubDate>
		<dc:creator>Sikachu!</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://sikachu.com/?p=751</guid>
		<description><![CDATA[Just found out something cool from reading &#8220;Don’t Know Metaprogramming In Ruby?&#8221; from RubyLearning blog. Consider this code snippet: class Person end &#160; class Student &#60; Person end &#160; class HighSchoolStudent &#60; Student end If you&#8217;re calling some method that&#8217;s undefined, let&#8217;s say we&#8217;re calling HighSchoolStudent#name Ruby will try to call the method in this [...]]]></description>
			<content:encoded><![CDATA[<p>Just found out something cool from reading &#8220;<a href="http://rubylearning.com/blog/2010/11/23/dont-know-metaprogramming-in-ruby/" target="_blank">Don’t Know Metaprogramming In Ruby?</a>&#8221; from RubyLearning blog. Consider this code snippet:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Person
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Student <span style="color:#006600; font-weight:bold;">&lt;</span> Person
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> HighSchoolStudent <span style="color:#006600; font-weight:bold;">&lt;</span> Student
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>If you&#8217;re calling some method that&#8217;s undefined, let&#8217;s say we&#8217;re calling <code>HighSchoolStudent#name</code> Ruby will try to call the method in this order:</p>
<ol>
<li>HighSchoolStudent#name</li>
<li>Student#name</li>
<li>Person#name</li>
<li>Object#name</li>
<li>Kernel#name</li>
<li>BasicObject#name</li>
<li>HighSchoolStudent#method_missing</li>
<li>Student#method_missing</li>
<li>Person#method_missing</li>
<li>Object#method_missing</li>
<li>Kernel#method_missing</li>
<li>BasicObject#method_missing</li>
</ol>
<p>From this example, you can see that not explicitly define method and capture it in <code>method_missing</code> might not be good in terms of the performance. So, what should you do?</p>
<p>I think the best way to do it, if you know that this method will get called again, would be define the &#8216;real&#8217; method after it gets called. That will reduce the call stack starting from the second run, resulting in faster code.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Let say we're defining method for #*_with_id here</span>
<span style="color:#9966CC; font-weight:bold;">def</span> method_missing<span style="color:#006600; font-weight:bold;">&#40;</span>name, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">super</span> <span style="color:#9966CC; font-weight:bold;">if</span> name !~ <span style="color:#006600; font-weight:bold;">/</span>_with_id$<span style="color:#006600; font-weight:bold;">/</span>
&nbsp;
  define_method <span style="color:#996600;">&quot;#{name}_with_id&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    instance_variable_get<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot;-&quot;</span> <span style="color:#006600; font-weight:bold;">+</span> instance_variable_get<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Hope this will make your code run faster, while still DRY.</p>
]]></content:encoded>
			<wfw:commentRss>http://sikachu.com/2010/11/method-missing-call-stack-in-ruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Gems — Follow up from my talk at #BarcampBKK4</title>
		<link>http://sikachu.com/2010/10/gems-barcampbkk4/</link>
		<comments>http://sikachu.com/2010/10/gems-barcampbkk4/#comments</comments>
		<pubDate>Fri, 29 Oct 2010 16:46:44 +0000</pubDate>
		<dc:creator>Sikachu!</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[BarcampBKK4]]></category>

		<guid isPermaLink="false">http://sikachu.com/?p=749</guid>
		<description><![CDATA[I think I should noted down two gems that I mentioned in my talk. Omniauth — a middleware that help you authenticate user to various SSO sites, such as Facebook Connect, Twitter, Google Account Devise — fully-functional authentication system. If you write an app that need authentication, this should be the solution for you. Writing [...]]]></description>
			<content:encoded><![CDATA[<p>I think I should noted down two gems that I mentioned in my talk.</p>
<ul>
<li><strong><a href="http://github.com/intridea/omniauth" target="_blank">Omniauth</a></strong> — a middleware that help you authenticate user to various SSO sites, such as Facebook Connect, Twitter, Google Account</li>
<li><strong><a href="http://github.com/plataformatec/devise" target="_blank">Devise</a></strong> — fully-functional authentication system. If you write an app that need authentication, this should be the solution for you. Writing your own authentication is discourage now. More on this later.</li>
</ul>
<p>I feel like I was saying 3 of them, but I can&#8217;t remember the other one. Anyway, don&#8217;t forget to dig into <a href="http://www.rubygems.org/" target="_blank">RubyGems</a> to find out some great gem to use in your project.</p>
]]></content:encoded>
			<wfw:commentRss>http://sikachu.com/2010/10/gems-barcampbkk4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>10 Things you should know about Ruby — #BarcampBKK4</title>
		<link>http://sikachu.com/2010/10/10-things-you-should-know-about-ruby/</link>
		<comments>http://sikachu.com/2010/10/10-things-you-should-know-about-ruby/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 15:20:28 +0000</pubDate>
		<dc:creator>Sikachu!</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[BarcampBKK4]]></category>

		<guid isPermaLink="false">http://sikachu.com/?p=743</guid>
		<description><![CDATA[I&#8217;ve done a talk about Ruby in Barcamp Bangkok 4 on Oct 24. Here is the slide in case someone want it. 10 things you should know about ruby You can download it if you want. This slide is CC-BY-NC-SA (as some photo I use require share-alike license.) One good question actually was the difference [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve done a talk about Ruby in Barcamp Bangkok 4 on Oct 24. Here is the slide in case someone want it.</p>
<div style="width:425px" id="__ss_5544219"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/sikachu/10-things-you-should-know-about-ruby" title="10 things you should know about ruby">10 things you should know about ruby</a></strong><object id="__sse5544219" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=10thingsyoushouldknowaboutruby-101024103648-phpapp01&#038;stripped_title=10-things-you-should-know-about-ruby&#038;userName=sikachu" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5544219" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=10thingsyoushouldknowaboutruby-101024103648-phpapp01&#038;stripped_title=10-things-you-should-know-about-ruby&#038;userName=sikachu" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
<p>You can <a href="http://www.slideshare.net/sikachu/10-things-you-should-know-about-ruby/download" target="_blank">download</a> it if you want. This slide is <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/" target="_blank">CC-BY-NC-SA</a> (as some photo I use require share-alike license.)</p>
<p>One good question actually was the difference between <code>module</code> and <code>class</code>. Actually, it just that simple — you cannot create object from a module.</p>
<p><code>Module</code> exists in Ruby to help you DRY up your code.</p>
<p>When you write several classes which have the same functionality, you better take that portion of the code out and put it in a module and <code>include</code> them back into your classes. That&#8217;s actually something Ruby coder loves to do — DRY up your code, and make it more maintainable.</p>
<hr />
<p>If you have any more question, feel free to post them in the comment section. I actually fumbled on my word a lot, because I didn&#8217;t get enough sleep last night. If you also want me to clearify something up, please let me know. Anyway, I hope you enjoyed it.</p>
]]></content:encoded>
			<wfw:commentRss>http://sikachu.com/2010/10/10-things-you-should-know-about-ruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>RailsCamp (Thailand) 2010</title>
		<link>http://sikachu.com/2010/10/railscamp-thailand-2010/</link>
		<comments>http://sikachu.com/2010/10/railscamp-thailand-2010/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 06:52:35 +0000</pubDate>
		<dc:creator>Sikachu!</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://sikachu.com/?p=739</guid>
		<description><![CDATA[เพิ่งทราบข่าวมาวันนี้ว่าที่ประเทศไทย จะมีคนจัดงาน RailsCamp แล้ว! RailsCamp (Thailand) 2010 ดีใจ + ตกใจนิดหน่อย เพราะเป็นโปรเจคที่คิดไว้ตั้งแต่เมื่อ 2-3 ปีที่แล้ว ตั้งแต่เมื่อตอนที่เขียน Rails ใหม่ๆ ว่าอยากให้มีงานที่เป็น Ruby on Rails Community ของคนไทย &#8230; ในเมื่อมีคนทำแล้ว ผมก็ขอสนับสนุนเต็มทีครับ ผมคงจะเตรียมเรื่องไปพูดนิดหน่อย ไม่แน่ใจเหมือนกันว่าเรื่องอะไร แต่ถ้าดูจาก Schedule ปัจจุบัน อาจจะได้พูดเรื่อง Behavior Driven Development using Cucumber หรือไม่ก็ Devise เพราะว่าเรื่องใหญ่ๆ อย่าง Rails 3 กับ Ruby 1.9 ได้อาจารย์ @rawitat กับคุณ @neokain พูดไปแล้ว ไปเจอกันโลด วันเสาร์ที่ 13 พฤศจิกายน 2553 [...]]]></description>
			<content:encoded><![CDATA[<p>เพิ่งทราบข่าวมาวันนี้ว่าที่ประเทศไทย จะมีคนจัดงาน RailsCamp แล้ว!</p>
<p><a href="http://www.thairor.com/2010/10/blog-post.html" target="_blank">RailsCamp (Thailand) 2010</a></p>
<p>ดีใจ + ตกใจนิดหน่อย เพราะเป็นโปรเจคที่คิดไว้ตั้งแต่เมื่อ 2-3 ปีที่แล้ว ตั้งแต่เมื่อตอนที่เขียน Rails ใหม่ๆ ว่าอยากให้มีงานที่เป็น Ruby on Rails Community ของคนไทย &#8230; ในเมื่อมีคนทำแล้ว ผมก็ขอสนับสนุนเต็มทีครับ ผมคงจะเตรียมเรื่องไปพูดนิดหน่อย ไม่แน่ใจเหมือนกันว่าเรื่องอะไร แต่ถ้าดูจาก Schedule ปัจจุบัน อาจจะได้พูดเรื่อง Behavior Driven Development using Cucumber หรือไม่ก็ Devise เพราะว่าเรื่องใหญ่ๆ อย่าง Rails 3 กับ Ruby 1.9 ได้อาจารย์ <a href="http://twitter.com/rawitat" target="_blank">@rawitat</a> กับคุณ <a href="http://twitter.com/neokain" target="_blank">@neokain</a> พูดไปแล้ว <img src='http://sikachu.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>ไปเจอกันโลด วันเสาร์ที่ 13 พฤศจิกายน 2553 เวลา 9:30-17:00 น. ณ Opendream</p>
<p>ปล. ได้เวลาปัดฝุ่นโปรเจคลับแล้วสินะ <img src='http://sikachu.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://sikachu.com/2010/10/railscamp-thailand-2010/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ruby 1.9.2 is out!!</title>
		<link>http://sikachu.com/2010/08/ruby-1-9-2-is-out/</link>
		<comments>http://sikachu.com/2010/08/ruby-1-9-2-is-out/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 16:08:33 +0000</pubDate>
		<dc:creator>Sikachu!</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Ruby 1.9]]></category>

		<guid isPermaLink="false">http://sikachu.com/?p=716</guid>
		<description><![CDATA[Just got the news in Twitter today that Ruby 1.9.2 is out! This is the Ruby that we&#8217;ve been long-awaits which shouldn&#8217;t have any strange compatibility issue with the upcoming Rails 3, and wayyyy faster than 1.8.7. The timing couldn&#8217;t be better, as we&#8217;re celebrating #whyday (@celebratewhyday) tomorrow (Aug 19.) On that day, you would [...]]]></description>
			<content:encoded><![CDATA[<p>Just got the news in Twitter today that <a href="http://twitter.com/yugui/status/21499615787" target="_blank">Ruby 1.9.2 is out</a>! This is the Ruby that we&#8217;ve been long-awaits which shouldn&#8217;t have any strange compatibility issue with the upcoming Rails 3, and wayyyy faster than 1.8.7.</p>
<p>The timing couldn&#8217;t be better, as we&#8217;re celebrating <a href="http://whyday.org/" target="_blank">#whyday</a> (<a href="http://twitter.com/celebratewhyday" target="_blank">@celebratewhyday</a>) tomorrow (Aug 19.) On that day, you would get hacking on something great! It&#8217;s the best time to trying to test out your application, or hacking something, using Ruby 1.9.2.</p>
<p>So what&#8217;re you waiting for? Download it, install it, and running your application on it. <a href="http://www.ruby-lang.org/en/news/2010/08/18/ruby-1-9-2-is-released/" target="_blank">Go grab it while it&#8217;s hot!</a></p>
<p>By the way, if you&#8217;re using the awesome <a href="http://rvm.beginrescueend.com/" target="_blank">RVM</a> (And why shouldn&#8217;t you??) Just go ahead and do:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">rvm update <span style="color: #660033;">--head</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> rvm reload <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> rvm <span style="color: #c20cb9; font-weight: bold;">install</span> 1.9.2 <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> rvm 1.9.2 <span style="color: #660033;">--default</span></pre></div></div>

<p>And have fun riding on this shiny Ruby! I warn you, it&#8217;s slippery. <img src='http://sikachu.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://sikachu.com/2010/08/ruby-1-9-2-is-out/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>If it&#8217;s already exists, then use it!</title>
		<link>http://sikachu.com/2010/08/if-its-already-exists-then-use-it/</link>
		<comments>http://sikachu.com/2010/08/if-its-already-exists-then-use-it/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 22:07:49 +0000</pubDate>
		<dc:creator>Sikachu!</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[protip]]></category>

		<guid isPermaLink="false">http://sikachu.com/?p=712</guid>
		<description><![CDATA[I recently came across this blog post from Computerworld, which seriously took all the respect I have for them from me: Not invented here: Apple&#8217;s secret applications In case you don&#8217;t want to read the whole article, here is the summary: This guy from Computerworld just talking about Apple&#8217;s secret on the software titles which [...]]]></description>
			<content:encoded><![CDATA[<p>I recently came across this blog post from Computerworld, which seriously took all the respect I have for them from me:</p>
<p><a href="http://blogs.computerworld.com/16540/not_invented_here_apples_secret_applications" target="_blank">Not invented here: Apple&#8217;s secret applications</a></p>
<p>In case you don&#8217;t want to read the whole article, here is the summary: This guy from Computerworld just talking about Apple&#8217;s secret on the software titles which Apple is generally using.</p>
<p>Seriously, I&#8217;d love to know the list of program that Apple are using, but the theme of that article is just so wrong; the writer tends to wrote in the tone that make Apple, a software company, should write every piece of software that they&#8217;re using by themselves.</p>
<p>Don&#8217;t believe me? Go back and read it yourself. I&#8217;ll sit here and sip a coffee waiting for you.</p>
<h3>The Real Truth</h3>
<p><a href="http://www.flickr.com/photos/pcsiteuk/4662997718/" title="Adobe CS5 box by pcsiteuk, on Flickr"><img src="http://farm5.static.flickr.com/4036/4662997718_f5c8ab2aa0_m.jpg" width="180" height="240" alt="Adobe CS5 box" align="right" style="padding: 5px" /></a>One question that I&#8217;m going to ask if you&#8217;re a developer: What kind of tools you&#8217;re currently using everyday? I believe you can give me the list of all sorts of tools that you&#8217;re using, such as Adobe Photoshop, Open Office, Netbeans, Vim, Emacs, etc. And since we&#8217;re the developer, why don&#8217;t we develop our own Photoshop-like application?</p>
<p>Well, because Photoshop is a professional tool, and it&#8217;s usable out of the box!<a href="footnote_1"><sup>1</sup></a></p>
<p>In nowadays, there&#8217;re so many tools that you can use to develop your application. You could buy it, or use an open source alternative. It just the matter of choice. Those tools are well-created and they&#8217;re helping you to get your job done as soon as you can.</p>
<p>Now, looking back at Apple. Do you think Apple has the employee power to write every software they are using? Yes they do! But why aren&#8217;t they? ..</p>
<p>Because they believes that they should spend those time creating something else!</p>
<h3>What&#8217;s I&#8217;m really meant to say</h3>
<p>Sorry, but I&#8217;m not going to say that that post is <del>bullshit</del> misleading. As a software developer, I think you should remember this: <strong>If it&#8217;s already exists, and working great, then go ahead and use it!</strong></p>
<p>For example, if you&#8217;re finding yourself having to write something up, let&#8217;s say &#8220;authentication system&#8221; for example, the first thing you&#8217;re going to do is not thinking about how to implements it yourself, but go to GitHub and try to find the one that fits your need.</p>
<p>Why am I suggesting this? Because when you&#8217;re developing one yourself, you just wasting your time creating something that&#8217;s already written.<a href="footnote_2"><sup>2</sup></a> Also, you never know that you might left a hole somewhere in your application, which would normally be patched already in those library/plugin. If you found any bug, then contact the developer and help them to get it fixed. It won&#8217;t only benefit you; It will also helping out other users that using the same piece of library as you do.</p>
<p>Remember, don&#8217;t wasting your time, use something that already exists to create something cool. It will definitely benefits you; and our planet.</p>
<hr />
<p>[<a name="footnote_1">1</a>] I said it&#8217;s usable, but I don&#8217;t think it&#8217;s bug-free. I still getting crashes with cryptic error message once in a while.</p>
<p>[<a name="footnote_2">2</a>]: If it&#8217;s not exists, then pat yourself in the back, as you&#8217;d have to write one yourself. <img src='http://sikachu.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Box Photo from <a href="http://www.flickr.com/photos/pcsiteuk/4662997718/" target="_blank">PC Site @ Flickr</a> under CC-BY-SA</p>
]]></content:encoded>
			<wfw:commentRss>http://sikachu.com/2010/08/if-its-already-exists-then-use-it/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>@rawitat&#8217;s #protip แด่ coder รุ่นน้องๆ</title>
		<link>http://sikachu.com/2010/08/protip-from-rawitat/</link>
		<comments>http://sikachu.com/2010/08/protip-from-rawitat/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 16:49:51 +0000</pubDate>
		<dc:creator>Sikachu!</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[protip]]></category>
		<category><![CDATA[rawitat]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://sikachu.com/?p=521</guid>
		<description><![CDATA[วันนี้พอดีตามอ่าน Twitter Stream แล้วเจออาจารย์ @rawitat (Blog) กำลังสอน coder รุ่นน้องๆ ผ่านทาง Twitter อยู่ &#8230; เลยขออนุญาตเอามารวมเป็น #protip หน่อยนะครับ ปล. เป็นรูปเซฟจาก Twitter Stream &#8230; แต่ว่ามันไม่ได้ต่อเนื่อง (จบในตอน) เพราะฉะนั้นจะอ่านจากล่างขึ้นบน หรือบนลงล่างก็ตามสะดวกครับ อ่านแล้วก็ได้ข้อคิดหลายๆ อย่างเหมือนกัน ขอบคุณมากครับ]]></description>
			<content:encoded><![CDATA[<p>วันนี้พอดีตามอ่าน Twitter Stream แล้วเจออาจารย์ <a href="http://twitter.com/rawitat" target="_blank">@rawitat</a> (<a href="http://www.rawitat.com/" target="_blank">Blog</a>) กำลังสอน coder รุ่นน้องๆ ผ่านทาง Twitter อยู่ &#8230; เลยขออนุญาตเอามารวมเป็น #protip หน่อยนะครับ</p>
<p>ปล. เป็นรูปเซฟจาก Twitter Stream &#8230; แต่ว่ามันไม่ได้ต่อเนื่อง (จบในตอน) เพราะฉะนั้นจะอ่านจากล่างขึ้นบน หรือบนลงล่างก็ตามสะดวกครับ</p>
<p><a href="http://www.flickr.com/photos/68535680@N00/4879134867" title="View '@rawitat's Protip' on Flickr.com"><img border="0"width="500"alt="@rawitat's Protip"src="http://farm5.static.flickr.com/4097/4879134867_7b244b2b6b_o.png"height="1358" style="border: 1px solid #ccc"/></a></p>
<p>อ่านแล้วก็ได้ข้อคิดหลายๆ อย่างเหมือนกัน ขอบคุณมากครับ <img src='http://sikachu.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://sikachu.com/2010/08/protip-from-rawitat/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Operator Precedence ใน Ruby</title>
		<link>http://sikachu.com/2009/12/operator-precedence-%e0%b9%83%e0%b8%99-ruby/</link>
		<comments>http://sikachu.com/2009/12/operator-precedence-%e0%b9%83%e0%b8%99-ruby/#comments</comments>
		<pubDate>Sat, 19 Dec 2009 05:44:00 +0000</pubDate>
		<dc:creator>Sikachu!</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[operator]]></category>

		<guid isPermaLink="false">http://sikachu.com/?p=385</guid>
		<description><![CDATA[Operator Precedence หรือลำดับสำคัญของตัวดำเนินการนั้น ถือเป็นหลักสำคัญของโปรแกรมเมอร์ ที่จะทำให้สามารถทำการเขียนอัลกอริธึมเพื่อแก้ไขปัญหาต่างๆ ได้ ในทางคณิตศาสตร์นั้น มักมีคนสรุปมันออกมาง่ายๆ ว่า &#8220;วงเล็บมาก่อน คูณหารก่อนบวกลบ&#8221; ถ้าใครเคยเห็น code ภาษา Ruby นั้น คงจะเคยเห็นว่า Ruby นั้นมีทั้ง operator &#038;&#038; และ &#124;&#124; เหมือนกับในภาษา C แล้วยังมี and กับ or ที่เพิ่มเข้ามาใน Ruby ซึ่งเป็นสิ่งที่ทำให้โค้ดนั้นดูสวยงามขึ้น อ่านง่ายขึ้นตามหลักของ Ruby ลองดูโค้ดด้านล่างนี้เป็นตัวอย่างครับ irb&#40;main&#41;:001:0&#62; dessert = &#34;Cheesecake&#34; =&#62; &#34;Cheesecake&#34; irb&#40;main&#41;:002:0&#62; drink = &#34;Coffee&#34; =&#62; &#34;Coffee&#34; irb&#40;main&#41;:003:0&#62; dessert == &#34;Cheesecake&#34; &#38;&#38; drink == &#34;Tea&#34; [...]]]></description>
			<content:encoded><![CDATA[<p>Operator Precedence หรือลำดับสำคัญของตัวดำเนินการนั้น ถือเป็นหลักสำคัญของโปรแกรมเมอร์ ที่จะทำให้สามารถทำการเขียนอัลกอริธึมเพื่อแก้ไขปัญหาต่างๆ ได้ ในทางคณิตศาสตร์นั้น มักมีคนสรุปมันออกมาง่ายๆ ว่า &#8220;วงเล็บมาก่อน คูณหารก่อนบวกลบ&#8221;</p>
<p>ถ้าใครเคยเห็น code ภาษา Ruby นั้น คงจะเคยเห็นว่า Ruby นั้นมีทั้ง operator <code>&#038;&#038;</code> และ <code>||</code> เหมือนกับในภาษา C แล้วยังมี <code>and</code> กับ <code>or</code> ที่เพิ่มเข้ามาใน Ruby ซึ่งเป็นสิ่งที่ทำให้โค้ดนั้นดูสวยงามขึ้น อ่านง่ายขึ้นตามหลักของ Ruby</p>
<p>ลองดูโค้ดด้านล่างนี้เป็นตัวอย่างครับ</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">irb<span style="color:#006600; font-weight:bold;">&#40;</span>main<span style="color:#006600; font-weight:bold;">&#41;</span>:001:<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&gt;</span> dessert = <span style="color:#996600;">&quot;Cheesecake&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Cheesecake&quot;</span>
irb<span style="color:#006600; font-weight:bold;">&#40;</span>main<span style="color:#006600; font-weight:bold;">&#41;</span>:002:<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&gt;</span> drink = <span style="color:#996600;">&quot;Coffee&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Coffee&quot;</span>
irb<span style="color:#006600; font-weight:bold;">&#40;</span>main<span style="color:#006600; font-weight:bold;">&#41;</span>:003:<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&gt;</span> dessert == <span style="color:#996600;">&quot;Cheesecake&quot;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span>
irb<span style="color:#006600; font-weight:bold;">&#40;</span>main<span style="color:#006600; font-weight:bold;">&#41;</span>:004:<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&gt;</span> dessert == <span style="color:#996600;">&quot;Cheesecake&quot;</span> <span style="color:#9966CC; font-weight:bold;">and</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span></pre></div></div>

<p>จะเห็นได้ว่า <code>&#038;&#038;</code> และ <code>and</code> นั้นให้ผลลัพธ์ที่เหมือนกัน ทำให้บางครั้งเราสามารถใช้ <code>and</code> มาแทนที่ <code>&#038;&#038;</code> และ <code>or</code> มาแทนที่ <code>||</code> ได้</p>
<p>แต่ entry นี้มันชื่อ Operator Precedence &#8230; เพราะฉะนั้นเรื่องราวมันไม่ได้จบแค่นี้ครับ คำถามต่อไปคือ คุณคิดว่าค่าของตัวแปร <code>first_order</code> และ <code>second_order</code> จะเป็นอย่างไร ในคำสั่งต่อไปนี้:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">first_order = dessert == <span style="color:#996600;">&quot;Cheesecake&quot;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span>
second_order = dessert == <span style="color:#996600;">&quot;Cheesecake&quot;</span> <span style="color:#9966CC; font-weight:bold;">and</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span></pre></div></div>

<p>คำตอบลองดูในนี้เลยครับ:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">irb<span style="color:#006600; font-weight:bold;">&#40;</span>main<span style="color:#006600; font-weight:bold;">&#41;</span>:005:<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&gt;</span> first_order = dessert == <span style="color:#996600;">&quot;Cheesecake&quot;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span>
irb<span style="color:#006600; font-weight:bold;">&#40;</span>main<span style="color:#006600; font-weight:bold;">&#41;</span>:006:<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&gt;</span> second_order = dessert == <span style="color:#996600;">&quot;Cheesecake&quot;</span> <span style="color:#9966CC; font-weight:bold;">and</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span>
irb<span style="color:#006600; font-weight:bold;">&#40;</span>main<span style="color:#006600; font-weight:bold;">&#41;</span>:007:<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&gt;</span> first_order
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span>
irb<span style="color:#006600; font-weight:bold;">&#40;</span>main<span style="color:#006600; font-weight:bold;">&#41;</span>:008:<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&gt;</span> second_order
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span></pre></div></div>

<p>อะไรนี่ 0_o!</p>
<p>จะเห็นได้จากบรรทัดที่ 005 และ 006 ว่า ทั้งคู่ก็คืนค่าออกมาเป็น <code>false</code> ทั้งนั้น แล้วทำไมค่าที่เก็บใน <code>first_order</code> กับ <code>second_order</code> มันกลับไม่เหมือนกัน</p>
<p>คำตอบคือ เป็นเพราะ Operator Precedence ของ Ruby ครับ</p>
<p>เหตุผลที่ <code>second_order</code> นั้นมีค่าเป็น <code>true</code> นั้น เพราะว่าใน Ruby นั้น <strong>เครื่องหมาย <code>=</code> จะมีลำดับขั้นที่สูงกว่า <code>and</code> และ <code>or</code> ครับ</strong></p>
<p>กล่าวคือ ในการเขียน statement ว่า</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> second_order = dessert == <span style="color:#996600;">&quot;Cheesecake&quot;</span> <span style="color:#9966CC; font-weight:bold;">and</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span></pre></div></div>

<p>เจ้าตัว Ruby Interpreter นั้น จะทำการ evaluate ออกมาเป็นอย่างนี้</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">001<span style="color:#006600; font-weight:bold;">&gt;</span> second_order = dessert == <span style="color:#996600;">&quot;Cheesecake&quot;</span> <span style="color:#9966CC; font-weight:bold;">and</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span>
002<span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>second_order = dessert == <span style="color:#996600;">&quot;Cheesecake&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">and</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span>
003<span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#9966CC; font-weight:bold;">and</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span>
004<span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span></pre></div></div>

<p>เพราะฉะนั้น คำสั่งข้างต้นที่ใช้ <code>and</code> นั้น ถ้าอยากให้มีผลเช่นเดียวกับ <code>&#038;&#038;</code> จำเป็นที่จะต้องใส่วงเล็บครอบให้เป็นอย่างนี้ครับ</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> second_order = <span style="color:#006600; font-weight:bold;">&#40;</span>dessert == <span style="color:#996600;">&quot;Cheesecake&quot;</span> <span style="color:#9966CC; font-weight:bold;">and</span> drink == <span style="color:#996600;">&quot;Tea&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>มีคนชอบบอกว่า Ruby เป็นภาษาที่แปลก &#8230; ผมเชื่อแล้วแหละว่าแปลกจริงๆ <img src='http://sikachu.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://sikachu.com/2009/12/operator-precedence-%e0%b9%83%e0%b8%99-ruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Optimize database query ด้วย :include</title>
		<link>http://sikachu.com/2009/08/optimize-database-query-%e0%b8%94%e0%b9%89%e0%b8%a7%e0%b8%a2-include/</link>
		<comments>http://sikachu.com/2009/08/optimize-database-query-%e0%b8%94%e0%b9%89%e0%b8%a7%e0%b8%a2-include/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 06:14:57 +0000</pubDate>
		<dc:creator>Sikachu!</dc:creator>
				<category><![CDATA[My Project]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[ActiveRecord]]></category>

		<guid isPermaLink="false">http://sikachu.com/?p=347</guid>
		<description><![CDATA[ในการเขียนโปรแกรมบน Ruby on Rails นั้น เรามักที่จะใช้ ActiveRecord ในการทำหน้าที่เป็น ORM ระหว่างตัว Application กับ database ซื่งทำให้การเรียก Record นั้น สามารถทำได้อย่างง่ายดาย เช่น ถ้าผมจะเรียกดู post ทั้งหมดที่มีอยู่ในระบบ ผมแค่สั่ง Post.find&#40;:all&#41; # หรือว่า Post.all ก็ได้ ใน Rails 2.x ซึ่งตรงนี้ ถ้าเราไปดูใน Log file จะพบว่า ActiveRecord นั้น จะใช้คำสั่งค้นหาข้อมูลประมาณนี้ครับ Post Load (0.1ms) SELECT * FROM &#34;posts&#34; (ผมใช่ sqlite3 เพราะฉะนั้น table name/field name จะถูกใส่ไว้ใน quote ครับ) ถ้าสมมุติในโปรแกรมนั้น [...]]]></description>
			<content:encoded><![CDATA[<p>ในการเขียนโปรแกรมบน <a href="http://rubyonrails.org/">Ruby on Rails</a> นั้น เรามักที่จะใช้ <a href="http://api.rubyonrails.org/classes/ActiveRecord/Base.html">ActiveRecord</a> ในการทำหน้าที่เป็น ORM ระหว่างตัว Application กับ database ซื่งทำให้การเรียก Record นั้น สามารถทำได้อย่างง่ายดาย เช่น ถ้าผมจะเรียกดู post ทั้งหมดที่มีอยู่ในระบบ ผมแค่สั่ง</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Post.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>    <span style="color:#008000; font-style:italic;"># หรือว่า Post.all ก็ได้ ใน Rails 2.x</span></pre></div></div>

<p>ซึ่งตรงนี้ ถ้าเราไปดูใน Log file จะพบว่า ActiveRecord นั้น จะใช้คำสั่งค้นหาข้อมูลประมาณนี้ครับ</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">  Post Load (0.1ms)   SELECT * FROM &quot;posts&quot;</pre></div></div>

<p>(ผมใช่ sqlite3 เพราะฉะนั้น table name/field name จะถูกใส่ไว้ใน quote ครับ)</p>
<p>ถ้าสมมุติในโปรแกรมนั้น เราได้ทำ <a href="http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html">Association</a> ระหว่าง Post และ Comment (Post has many comments) และระหว่าง Comment กับ User (comment belongs to user)</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Post <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  has_many <span style="color:#ff3333; font-weight:bold;">:comments</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># ...</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Comment <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  belongs_to <span style="color:#ff3333; font-weight:bold;">:post</span>
  belongs_to <span style="color:#ff3333; font-weight:bold;">:user</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># ...</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>ถ้าเราต้องการจะแสดงผล comment แต่ละอันด้วย เราก็สามารถทำได้โดยเรียกเมธอด <code>#comments</code> ที่ถูกสร้างขึ้นมาอัตโนมัติโดยการทำ association และเช่นเดียวกัน ถ้าเราต้องการแสดงด้วยว่า comment นั้นถูกเขียนโดยใคร เราก็สามารถเรียกเมธอด <code>#user</code> บน comment เช่นกัน</p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&lt;%</span> Post.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#5A0A0A; font-weight:bold;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>post<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  &lt;!-- display post --&gt;
  <span style="color:#006600; font-weight:bold;">&lt;%</span> post.<span style="color:#9900CC;">comments</span>.<span style="color:#5A0A0A; font-weight:bold;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>comment<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    By: <span style="color:#006600; font-weight:bold;">&lt;%</span>= comment.<span style="color:#9900CC;">user</span>.<span style="color:#9900CC;">username</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    &lt;!-- display comments --&gt;
  <span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></div></div>

<p>คราวนี้ สมมุติว่าบล็อกเรามีทั้งหมด 10 Post แล้วแต่ละอันมี 5 comment &#8230; SQL ที่ออกมานั้น จะเป็นประมาณนี้ครับ</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">  Post Load (0.1ms)   SELECT * FROM &quot;posts&quot;
  Comment Load (0.5ms)   SELECT * FROM &quot;comments&quot; WHERE (&quot;comments&quot;.
&quot;post_id&quot; = '1')
  User Load (0.2ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; = '5')
  User Load (0.2ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; = '24')
  User Load (0.2ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; = '30')
  User Load (0.2ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; = '4')
  CACHE (0.0ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; = '5')
  Comment Load (0.3ms)   SELECT * FROM &quot;comments&quot; WHERE (&quot;comments&quot;.
&quot;post_id&quot; = '2')
  User Load (0.2ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; = '38')
  User Load (0.2ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; = '14')
  User Load (0.2ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; = '40')
  User Load (0.2ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; = '2')
  User Load (0.2ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; = '9')
  ...</pre></div></div>

<p>จะเห็นได้ว่า ในสถานการณ์ที่แย่ที่สุดนั้น (user ที่มา comment แต่ละ post นั้น ไม่ตรงกันเลย เป็นต้น) ActiveRecord จำเป็นต้องทำการ Query ทั้งหมด <code>1 + 10 + (10 * 5)  = 61</code> ครั้ง ซึ่งไม่มีประสิทธิภาพเลยครับ เพราะเปลือง Query มากมาย</p>
<p>ดังนั้น เพื่อให้ Query ทั้งหมดนี่มีประสิทธิภาพมากขึ้น ActiveRecord จึงมี key หนึ่งชื่อว่า <code><a href="http://api.rubyonrails.org/classes/ActiveRecord/Base.html">:include</a></code> เอาไว้สำหรับสั่งว่าให้ ActiveRecord นั้นทำการโหลด Model ที่ associates กับ object นี้ขึ้นมาด้วยพร้อมๆ กันเลย เพื่อประหยัด Query ครับ เพราะฉะนั้นโค้ดในการค้นหาของเราจะเปลี่ยนเป็น</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Post.find(:all, :include =&gt; {:comments =&gt; :user}).each do |post|
  # ... display post
  post.comments.each do |comment|
    By: <span style="color:#006600; font-weight:bold;">&lt;%</span>= comment.<span style="color:#9900CC;">user</span>.<span style="color:#9900CC;">username</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    # ... display comments
  end
end</pre></div></div>

<p>แล้วผลของมันน่ะหรอครับ? 61 query -> 3 queries ครับ!</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">  Post Load (0.1ms)   SELECT * FROM &quot;posts&quot;
  Comment Load (0.3ms)   SELECT * FROM &quot;comments&quot; WHERE (&quot;comments&quot;.
&quot;post_id&quot; IN (1, 2, 3, 4, 5))
  User Load (1.3ms)   SELECT * FROM &quot;users&quot; WHERE (&quot;user&quot;.&quot;id&quot; IN (5, 24,
30, 4, 2, 38, 14, 40, 2, 9, 23, 41, 48, 50, 32, 10, 48)</pre></div></div>

<p>เพราะฉะนั้นการใช้ <code>:include</code> นั้น เป็นการ optimize query อย่างได้ผลทีเดียวละครับ โดยจะเห็นได้ว่าเรายังสามารถโหลด model แบบ nested ได้โดยการใช้ Hash และโหลดโมเดลหลายๆ อันพร้อมกันโดยใช้ Array ครับ อย่างเช่นถ้าเราต้องการโหลด Attachments จาก Comment และโหลด Tags จาก Post ด้วย เราก็สามารถใช้คำสั่งอย่างนี้ได้ครับ</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Post.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span>, :<span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#123;</span>:comments <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user</span>, <span style="color:#ff3333; font-weight:bold;">:attachments</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#125;</span>, 
<span style="color:#ff3333; font-weight:bold;">:tags</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p><strong>คำเตือน: Use it, but don&#8217;t abuse it!</strong></p>
<p>ในบางครั้ง การใช้ <code>:include</code> นั้น อาจจะทำให้เวลาในการ query นั้นลดลงได้ถ้าเทียบกับการ query object เล็กๆ หลายๆ ครั้งแทน เพราะฉะนั้นมันไม่ใช่สิ่งที่เวิร์คที่สุดครับ ต้องปรับใช้ให้เข้ากับงานซะมากกว่า โดยที่ผมแนะนำให้<strong>ใช้ <code>#find</code> method ตามปกติก่อน แล้วจึงค่อยเพิ่ม <code>:include</code> เข้าไปถ้าเราเห็นว่ามีการ query record จำนวนมากๆ</strong>ครับ &#8230; ถือซะว่าการใช้ <code>:include</code> นั้นเป็นการ refactor code ครับ และไม่ใช่สิ่งที่ต้องมาคิดตั้งแต่แรกว่าตรงนี้ต้องใช้มันหรือไม่ <img src='http://sikachu.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://sikachu.com/2009/08/optimize-database-query-%e0%b8%94%e0%b9%89%e0%b8%a7%e0%b8%a2-include/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

