<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>PunNeng on the Edge - Home</title>
  <id>tag:weblog.punneng.net,2009:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://weblog.punneng.net/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://weblog.punneng.net/" rel="alternate" type="text/html"/>
  <updated>2009-02-16T18:33:36Z</updated>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2009-02-16:1039</id>
    <published>2009-02-16T18:32:00Z</published>
    <updated>2009-02-16T18:33:36Z</updated>
    <category term="General"/>
    <link href="http://weblog.punneng.net/2009/2/16/a-quick-facebook-connect-guide" rel="alternate" type="text/html"/>
    <title>A quick facebook connect guide</title>
<content type="html">
            &lt;p&gt;Here is a quick todo&lt;br /&gt;
&lt;a href=&quot;http://wiki.developers.facebook.com/index.php/Trying_Out_Facebook_Connect&quot;&gt;http://wiki.developers.facebook.com/index.php/Trying&lt;em&gt;Out&lt;/em&gt;Facebook_Connect&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;There is a tricky part. It is when you are logged in, you have to make the page reload automatically.&lt;br /&gt;
Fortunately, there is a javascript helper&lt;br /&gt;
&lt;a href=&quot;http://www.somethingtoputhere.com/therunaround/fbconnect.js&quot;&gt;http://www.somethingtoputhere.com/therunaround/fbconnect.js&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Usage:&lt;/h3&gt;

&lt;p&gt;put these codes below to your page, it will render the link to log in.  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  7&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  8&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  9&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 10&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 11&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 12&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 13&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 14&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 15&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 16&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 17&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 18&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 19&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;MetaTagAll&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/javascripts/fbconnect.js&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;MetaTagAll&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;text/javascript&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;MetaTagAll&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;MetaTagAll&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;MetaTagAll&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;text/javascript&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;&lt;/span&gt;/&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;MetaTagInline&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;#&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;onclick&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;FB.Connect.requireSession(); return false;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;&amp;lt;!--&lt;/span&gt; this can be a text link or image tag &lt;span class=&quot;Comment&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;MetaTagInline&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;image&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;value&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;facebook&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/images/buttons/btn_facebook.gif&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;  /&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;MetaTagInline&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;text/javascript&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;gt;&lt;/span&gt; FB&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;init&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;YOUR_APP_KEY&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;xd_receiver.htm&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;text/javascript&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;  FB&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;Connect&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;ifUserConnected&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Storage&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;   &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;//&lt;/span&gt; will be invoked if user is connected and refresh the site to the callback url(explain below)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;   &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;Support&quot;&gt;window&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;onload&lt;/span&gt; = &lt;span class=&quot;Storage&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;{&lt;/span&gt; facebook_onload&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Constant&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;  &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;  &lt;span class=&quot;Storage&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;   &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;//&lt;/span&gt; will be invoked if user is not connected&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;   &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;Support&quot;&gt;window&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;onload&lt;/span&gt; = &lt;span class=&quot;Storage&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;{&lt;/span&gt; facebook_onload&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;Constant&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;  &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;  &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;h3&gt;Changing the callback url:&lt;/h3&gt;

&lt;p&gt;in fbconnect.js, there are codes:&lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Storage&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;refresh_page&lt;/span&gt;() {
  &lt;span class=&quot;Support&quot;&gt;window&lt;/span&gt;.&lt;span class=&quot;SupportConstant&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;index.php&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;
}
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;index.php is needed to be changed to the callback path.&lt;br /&gt;
This method will be called after the user is connected.  &lt;/p&gt;

&lt;h3&gt;Getting the facebook id:&lt;/h3&gt;

&lt;p&gt;When it's redirected to the url above, the facebook id or the user details should be in the session of the site. You need to echo the session to see what keys are in the session.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-12-23:1030</id>
    <published>2008-12-23T22:46:00Z</published>
    <updated>2008-12-23T22:50:33Z</updated>
    <category term="Merb"/>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.net/2008/12/23/merb-gets-merged-into-rails-3" rel="alternate" type="text/html"/>
    <title>Merb gets merged into Rails 3!</title>
<content type="html">
            มีของขวัญวันปีใหม่+คริสต์มาสมาฝากครับ&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Merb 2.0 และ Rails 3.0 จะกลายเป็นสิ่งเดียวกัน&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
ผู้พัฒนาทั้งสองฝั่ง คือ Merb กับ Rails ตัดสินใจ ที่จะพัฒนา framework ทั้งสองตัวนี้ร่วมกัน โดยจะเอาของดีหลักๆ ของ Merb ไปใส่ใน Rails คือ
&lt;ul&gt;
	&lt;li&gt;Agnosticism - คือการไม่ยึดติด เช่น ไม่ชอบ AcitveRecord เอาตัวอื่นได้ไหม&lt;/li&gt;
	&lt;li&gt;Modularity - คือการแยกเป็นส่วนๆ แยกไปเลยเป็น module ไว้ทำอะไร เวลาเขียน code ก็อย่าให้มันตีกัน&lt;/li&gt;
	&lt;li&gt;Improved performance - แน่นอน performance ดีขึ้น เร็วขึ้น&lt;/li&gt;
	&lt;li&gt;Public API - บังคับให้คนใช้ คือบางกรณี ดันไปเรียก method ที่ protected/private(ไม่เห็นใน API) ไว้ แต่ถ้าที่ protected/private นั้น มีการ update ล่ะ แน่นอน พังแน่ๆ ก็ต้องตามไป update code ใหม่&lt;/li&gt;
&lt;/ul&gt;
แต่ก็ใช่ว่า Merb จะตายไป ทีมก็ยังพัฒนาต่อ และก็ยังพัฒนาร่วมกับ Rails ด้วย แต่ออก Rails 3.0 เมื่อไหร่ มันจะเป็นสิ่งเดียวกัน&lt;br /&gt;
&lt;br /&gt;
สำหรับคนที่ใช้ Merb อยู่ เขาแนะนำให้ใช้ต่อเลย เพราะมันคงใช้เวลาสักพักใหญ่ๆ ในการปรับปรุง ถ้า Rails 3.0 ออกมาอย่างเป็นทางการ ก็ไม่ต้องห่วงเพราะ Yehuda Katz บอกว่า&lt;br /&gt;
&lt;blockquote&gt;You will not be left in the cold and we’re going to do everything to make sure that your applications don’t get stuck in the past.&lt;/blockquote&gt;&lt;br /&gt;
สำหรับคนที่กำลังศึกษาหรือสนใจที่จะศึกษา Merb ผมว่าน่าจะลองเลยครับ เพราะในที่สุดแล้ว แนวทางการเขียนหลักๆ ก็คงจะไม่ต่างจากที่เขียน Merb ในทุกวันนี้หรอก รูัก่อน เป็นก่อน ย่อมได้เปรียบ&lt;br /&gt;
&lt;br /&gt;
ปล. นอกจากผมและสมาชิก codegent แล้ว มีใครใช้ Merb ในงานจริงๆ บ้างเนี่ย&lt;br /&gt;
&lt;br /&gt;
links ที่เกี่ยวข้อง&lt;br /&gt;
&lt;a href=&quot;http://merbist.com/2008/12/23/rails-and-merb-merge/&quot;&gt;http://merbist.com/2008/12/23/rails-and-merb-merge/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://yehudakatz.com/2008/12/23/rails-and-merb-merge/&quot;&gt;http://yehudakatz.com/2008/12/23/rails-and-merb-merge/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://weblog.rubyonrails.org/2008/12/23/merb-gets-merged-into-rails-3&quot;&gt;http://weblog.rubyonrails.org/2008/12/23/merb-gets-merged-into-rails-3&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://brainspl.at/articles/2008/12/23/merb-is-rails&quot;&gt;http://brainspl.at/articles/2008/12/23/merb-is-rails&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://splendificent.com/2008/12/the-merb-rails-merger-announcement-an-inside-opinion/&quot;&gt;http://splendificent.com/2008/12/the-merb-rails-merger-announcement-an-inside-opinion/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://rubyonrails.org/merb&quot;&gt;http://rubyonrails.org/merb&lt;/a&gt;&lt;br /&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-11-09:1026</id>
    <published>2008-11-09T15:19:00Z</published>
    <updated>2008-11-09T15:23:29Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.net/2008/11/9/ruby-on-rails-fragment-caching" rel="alternate" type="text/html"/>
    <title>Ruby on Rails :: Fragment Caching</title>
<content type="html">
            &lt;p&gt;fragment caching เป็น post ต่อจาก &lt;a href=&quot;http://weblog.punneng.net/2008/10/5/ruby-on-rails-page-caching&quot;&gt;page caching&lt;/a&gt; กับ &lt;a href=&quot;http://weblog.punneng.net/2008/10/26/ruby-on-rails-action-caching&quot;&gt;action caching&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;ชื่อมันก็บอกอยู่แล้วว่าทำ cache แบบเป็นชิ้นๆ สิ่งที่นิยมทำ cache แบบนี้คือการ render เป็นส่วนๆ ในฝั่งของ html template ตัวอย่าง  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;title&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%&lt;/span&gt; cache &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
  a lot of text or ruby expression hear and it is 
  &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; &lt;span class=&quot;SupportFunction&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;partial&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;topic&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;locals&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;time&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;now&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&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;ในที่นี้ มันจะ cache ใน block ที่กำหนดไว้ โดยค่า default ในการอ้างถึงจะเป็นชื่อ action และ controller เช่น ถ้าจะ clear cache ก้อนนี้ จะเรียกใช้  &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;expire_fragment(:controller =&gt; &quot;topics&quot;, :action =&gt; &quot;list&quot;)  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ในความเป็นจริงแล้ว เราอาจจะมี cache หลายที่ในหนึ่งหน้า เลยมี options เพิ่มมา สำหรับกำหนดชื่อให้มันอีก  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;cache(:action =&amp;gt; &amp;quot;list&amp;quot;, :action_suffix =&amp;gt; &amp;quot;time&amp;quot;)
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;ตัว action_suffix จะเป็นสิ่งที่ทำให้เราสามารถเข้าถึง cache ก้อนนี้ได้ เช่น&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;expire_fragment(:controller =&gt; &quot;topics&quot;, :action =&gt; &quot;list&quot;, :action_suffix =&gt; &quot;time&quot;)  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;แล้วมันเอาไปเก็บไว้ที่ไหน??&lt;br /&gt;
จริงๆ ผมเขียนไปในตอนที่แล้วแล้ว ว่ามันเก็บไว้เป็น hash โดยใช้ &lt;a href=&quot;http://api.rubyonrails.org/classes/ActiveSupport/Cache/MemoryStore.html&quot;&gt;ActiveSupport::Cache::MemoryStore&lt;/a&gt; เป็นตัวบันทึก&lt;/p&gt;

&lt;p&gt;รายละเอียดเพิ่มเติมดูได้ใน &lt;a href=&quot;http://api.rubyonrails.org&quot;&gt;API&lt;/a&gt; ได้เลย&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-10-26:1024</id>
    <published>2008-10-26T14:09:00Z</published>
    <updated>2008-10-26T14:10:18Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.net/2008/10/26/ruby-on-rails-action-caching" rel="alternate" type="text/html"/>
    <title>Ruby on Rails :: Action Caching</title>
<content type="html">
            &lt;p&gt;ต่อจาก&lt;a href=&quot;http://weblog.punneng.net/2008/10/5/ruby-on-rails-page-caching&quot;&gt;คราวที่แล้ว&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;ใน API ของ rails เอง เขียนอธิบายไว้ว่า มันไม่ได้ต่างอะไรกับ page caching มาก แต่ผมว่ามันค่อนข้างต่างเลยแหละ ถ้าจะพิจารณาการบันทึกข้อความสำหรับ cache  &lt;/p&gt;

&lt;p&gt;เรื่อง configuration ก็เหมือนกับ page caching ครับ จะข้ามไป  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;แล้ว Action Caching ใช้ตอนไหน ??&lt;/strong&gt;&lt;br /&gt;
ก็ใช้ตอนที่เราต้องใช้ filter เช่น before_filter หรือ after_filter&lt;br /&gt;
ตัวอย่างที่เขาใช้อธิบายใน API คือ เรือ่ง authentication ใน code หน้าตาจะประมาณนี้  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;JEntityNameType&quot;&gt;ListsController&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; ApplicationController&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;SupportFunction&quot;&gt;before_filter&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;authenticate&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;except&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;public&lt;/span&gt;
    caches_page   &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;public&lt;/span&gt;
    caches_action &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;index&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;show&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;feed&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;จากตัวอย่างข้างบน จะมีการ authentication ที่ action index, show และ feed 
ถ้าหากไม่ใช้ caches_action แต่ไปใช้ caches_page แทน มันจะเขียน file.html แล้วมันจะไม่วิ่งเข้า before_filter :authetication&lt;br /&gt;
ทางแก้ก็คือ ใช้ caches_action แทน  &lt;/p&gt;

&lt;p&gt;โดยการเก็บ cache มันจะไปใช้ความสามารถของ Fragment Cache แทน สำหรับ Fragment Cache ไว้ตอนหน้าครับ
ซึ่งมันจะเก็บ cache ไว้ที่ Hash ไว้ใน ActiveSupport::Cache::MemoryStore ครับ ถ้าเรา restart server มันก็จะหายไป ไม่ได้เก็บถาวรเหมือน Page Caching  &lt;/p&gt;

&lt;p&gt;ในการ clear action caching ก็ไม่ได้ซับซ้อนอะไร เพียงแค่  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;expire_action &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;lists&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;index&lt;span class=&quot;String&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;นอกจากนี้ยังใส่เงื่อนไขได้ด้วย เช่น&lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  7&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  8&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  9&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;JEntityNameType&quot;&gt;ListsController&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; ApplicationController&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;SupportFunction&quot;&gt;before_filter&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;authenticate&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;except&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;public&lt;/span&gt;
    caches_page   &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;public&lt;/span&gt;
    caches_action &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;index&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;if&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Support&quot;&gt;Proc&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;new&lt;/span&gt; { |&lt;span class=&quot;Variable&quot;&gt;c&lt;/span&gt;| &lt;span class=&quot;Keyword&quot;&gt;!&lt;/span&gt;c.&lt;span class=&quot;Entity&quot;&gt;request&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;format&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;json?&lt;/span&gt; } &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; cache if is not a JSON request&lt;/span&gt;
    caches_action &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;show&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;cache_path&lt;/span&gt; =&amp;gt; { &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;project&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;&amp;amp;&lt;/span&gt;gt; &lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt; }
    caches_action &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;feed&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;cache_path&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Support&quot;&gt;Proc&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;new&lt;/span&gt; { |&lt;span class=&quot;Variable&quot;&gt;controller&lt;/span&gt;|
      controller.&lt;span class=&quot;Entity&quot;&gt;params&lt;/span&gt;[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user_id&lt;/span&gt;] &lt;span class=&quot;Keyword&quot;&gt;?&lt;/span&gt;
        controller.&lt;span class=&quot;Entity&quot;&gt;send&lt;/span&gt;(&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user_list_url&lt;/span&gt;, c.&lt;span class=&quot;Entity&quot;&gt;params&lt;/span&gt;[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;user_id&lt;/span&gt;], c.&lt;span class=&quot;Entity&quot;&gt;params&lt;/span&gt;[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;id&lt;/span&gt;]) :
        controller.&lt;span class=&quot;Entity&quot;&gt;send&lt;/span&gt;(&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;list_url&lt;/span&gt;, c.&lt;span class=&quot;Entity&quot;&gt;params&lt;/span&gt;[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;id&lt;/span&gt;]) }
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;ข้อมูลเพิ่มเติมดูได้ที่ &lt;a href=&quot;http://api.rubyonrails.org/classes/ActionController/Caching/Actions.html&quot;&gt;API&lt;/a&gt; เลยครับ&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-10-05:1022</id>
    <published>2008-10-05T18:17:00Z</published>
    <updated>2008-10-05T18:18:48Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.net/2008/10/5/ruby-on-rails-page-caching" rel="alternate" type="text/html"/>
    <title>Ruby on Rails :: Page caching</title>
<content type="html">
            &lt;p&gt;รีบปั่นก่อน ก่อนที่ merb 1.0 จะออกมา เดี๋ยวจะไม่ได้เขียน blog สักเท่าไหร่ เพราะคงไปนั่งวุ่นอยู่กับ merb นี่แหละ  &lt;/p&gt;

&lt;p&gt;post อันนี้ คงจะอยู่ทั้ง blog ผม และ &lt;a href=&quot;http://www.rails66.com/blog&quot;&gt;rails66.com&lt;/a&gt; ด้วย เขียนทีเดียว แปะมันทั้งสองที่  &lt;/p&gt;

&lt;p&gt;วิธีการทีจะลดการทำงานของ server ได้ หนึ่งวิธีในนั้นที่ช่วยได้เยอะเลยคือการทำ cache&lt;br /&gt;
ใน Rails เองมีการทำ cache อยู่ 4 ระดับ คือ  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;page caching&lt;/li&gt;
&lt;li&gt;action caching&lt;/li&gt;
&lt;li&gt;fragment caching&lt;/li&gt;
&lt;li&gt;sql caching  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;และตัวควบคุมการลบ cache พวกนี้ ก็คือ  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sweeper  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;อันแรกนี้ ขอเป็น page caching ก่อน&lt;/p&gt;

&lt;p&gt;ซึ่ง page caching เนี่ย มันจะเก็บ output ไว้เป็น file โดย save ไว้เป็น html เลย โดยเก็บไว้ใน public/ ซึ่งสามารถเปลี่ยนที่เก็บได้ เดี๋ยวค่อยว่ากันอีกที เมื่อมันมี request มา มันจะวิ่งเข้าที่ file นี้แทน แทนที่จะวิ่งไปที่ controller แล้วก็ทำงานตามที่เราเขียนไว้  &lt;/p&gt;

&lt;p&gt;การทำ page caching นี้ เหมาะสำหรับอะไรที่มันอยู่นานๆ แล้วคงจะไม่เปลี่ยน เช่นระบบ blog ซึ่งปกติ จะไม่ค่อยแก้ไขอะไรเท่าไหร่ จะทำการลบ cache นี้ออก ก็ต่อเมื่อมีการ update หรือมีการเพิ่มข้อคิดเห็น(comment) เป็นต้น  &lt;/p&gt;

&lt;p&gt;เริ่มต้นด้วยการเปิด cache ก่อน โดยปกติ ถ้าเราทำงานใน development environment มันจะปิดระบบ cache ทั้งหมด แต่ถ้าสลับมาเป็น production environment มันจะทำการเปิด cache ทุกอย่าง ลองดูใน config/environments/production.rb  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;config.&lt;span class=&quot;Entity&quot;&gt;action_controller&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;perform_caching&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;true&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;ไปตั้งค่าให้เป็น true ใน config/environments/development.rb มันก็จะไปเปิดตัวจัดการ cache ให้  &lt;/p&gt;

&lt;p&gt;สมมติว่าถ้าต้องการเปลี่ยน path ในการเก็บ cache ก็ใส่เพิ่มไปว่า  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;config.&lt;span class=&quot;Entity&quot;&gt;action_controller&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;page_cache_directory&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;RAILS_ROOT&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/public/wherever/you/want/&lt;span class=&quot;String&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;เวลาเข้าถึงก็ http://localhost:3000/wherever/you/want/file  &lt;/p&gt;

&lt;p&gt;วิธีเซ็ต page caching ก็ง่ายๆ เราใส่ไปใน controller ว่า  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;JEntityNameType&quot;&gt;PostsController&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; ApplicationController&lt;/span&gt;&lt;/span&gt;
  caches_page &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;show&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;show&lt;/span&gt;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;post&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;Post&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; params[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;id&lt;/span&gt;]
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;แค่นี้เอง  &lt;/p&gt;

&lt;p&gt;เวลาจะลบ cache สมมติว่าเราจะลบ หลังจากที่เรา update content ของเรา เราก็ใส่ใน controller ไปว่า  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  7&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  8&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  9&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;update&lt;/span&gt;
  &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;post&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;Post&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;find&lt;/span&gt; params[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;id&lt;/span&gt;]
  &lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;post&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;update_attributes&lt;/span&gt; params[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;post&lt;/span&gt;]
    flash[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;notice&lt;/span&gt;] &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;Updated&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    expire_page &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;show&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;id&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;post&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;id&lt;/span&gt;
    &lt;span class=&quot;SupportFunction&quot;&gt;redirect_to&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;index&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;else&lt;/span&gt; 
    &lt;span class=&quot;SupportFunction&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;edit&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;expire_page จะไปทำการลบให้เองเลย สบายมากๆ (รออีกสักหน่อย เดี๋ยวจะเขียนเรือง sweeper มาจัดการตรงนี้ครับ)  &lt;/p&gt;

&lt;p&gt;แต่ก็ใช่ว่าจะไม่มีปัญหาเลย เพราะหลังจาก update เสร็จแล้ว เราควรที่จะแสดงข้อความอะไรบอกหน่อย ในที่นี้ผมใส่ไปใน flash[:notice] ปัญหามันคือ มันจะเก็บ cache ไว้ในขณะที่มีข้อความนี้อยู่บนหน้า เพราะมันจะเก็บตอนที่เราสั่ง redirect_to  &lt;/p&gt;

&lt;p&gt;วิธีซ่อมแบบไม่ลงแรงเลยคือ ใช้ plugin ที่ชื่อว่า &lt;a href=&quot;http://github.com/look/cacheable-flash/tree/master&quot;&gt;Cacheable Flash&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;เอามาจาก &lt;a href=&quot;http://www.rails66.com/blog/2008/10/03/%e0%b8%99%e0%b8%b1%e0%b9%88%e0%b8%87%e0%b9%80%e0%b8%97%e0%b8%b5%e0%b8%a2%e0%b8%99%e0%b9%80%e0%b8%82%e0%b8%b5%e0%b8%a2%e0%b8%99%e0%b8%82%e0%b9%88%e0%b8%b2%e0%b8%a712/&quot;&gt;นั่งเทียนเขียนข่าว#12&lt;/a&gt; ครับ   &lt;/p&gt;

&lt;p&gt;โดยวิธีการมันก็ง่ายๆ ครับ คือเก็บข้อความไว้ใน cookie ก่อน แล้วก็ดึงมาแสดงผลด้วย javascript อีกที&lt;br /&gt;
แต่ผมไม่ค่อยชอบ น่าจะมีตรวจว่ามี flash หรือเปล่า ก็เลยลงมืองัดแงะปลุกปล้ำเสียหน่อยได้หน้าตาแบบนี้  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;caches_page &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;show&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;if&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Support&quot;&gt;Proc&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;new&lt;/span&gt;{ |&lt;span class=&quot;Variable&quot;&gt;p&lt;/span&gt;| p.&lt;span class=&quot;Entity&quot;&gt;request&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;session&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;data&lt;/span&gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;flash&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;].&lt;span class=&quot;Entity&quot;&gt;blank?&lt;/span&gt;}
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;คือ cache ถ้า flash message ว่าง&lt;br /&gt;
ดูเท่กว่าเยอะ  &lt;/p&gt;

&lt;p&gt;ปล. อาทิตย์หน้ามาต่อกับ action caching ครับ  &lt;/p&gt;

&lt;p&gt;ข้อมูลจาก &lt;a href=&quot;http://api.rubyonrails.org/classes/ActionController/Caching/Pages.html&quot;&gt;rails api&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-08-02:1016</id>
    <published>2008-08-02T13:18:00Z</published>
    <updated>2008-08-02T13:18:54Z</updated>
    <category term="Merb"/>
    <link href="http://weblog.punneng.net/2008/8/2/merb-on-dreamhost" rel="alternate" type="text/html"/>
    <title>Merb on Dreamhost</title>
<content type="html">
            &lt;h3&gt;Get started&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Make sure that Ruby on Rails Passenger (mod_rails) is enabled on your domain.&lt;/strong&gt;&lt;br /&gt;
To do that, go to the &lt;a href=&quot;https://panel.dreamhost.com/index.cgi?tree=domain.manage&amp;amp;&quot;&gt;Domains &gt; Manage Domains&lt;/a&gt; section of your panel and then click the &quot;Edit&quot; link next to your domain. On the next page make sure &quot;Ruby on Rails Passenger (mod_rails)?&quot; is enabled. Also, specify your web directory and then click the &quot;Save Changes&quot; button.  &lt;/p&gt;

&lt;h3&gt;Create a directory for compiled packages and Gems&lt;/h3&gt;

&lt;p&gt;I recommend Ruby 1.8.6 at for running Merb and it is Ruby 1.8.5 on Dreamhost currently. Fortunately, Dreamhost allows installing the own gems and pacakges and &lt;a href=&quot;http://www.nateclark.com&quot;&gt;nateclark&lt;/a&gt; has &lt;a href=&quot;http://www.nateclark.com/articles/2006/10/20/dreamhost-your-own-packages-and-gems&quot;&gt;already blogged&lt;/a&gt; which is really good way to follow.  &lt;/p&gt;

&lt;p&gt;Actually, I needed Readline also but I couldn't get it work. Can anyone get it work?  &lt;/p&gt;

&lt;h3&gt;Install Merb&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://merb.4ninjas.org/&quot;&gt;4 ninjas&lt;/a&gt; has already written how to. Install Merb locally and there will be a few problems when you install do&lt;em&gt;mysql(do&lt;/em&gt;postgres and do_sqlite3) if you prefer DataMapper. On Ubuntu, it can't find lmysqlclient or can't find mysql.h&lt;br /&gt;
To fix that problems,&lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ sudo apt-get install mysql
$ sudo apt-get install libmysqlclient15-dev&lt;/pre&gt;  

&lt;p&gt;On OSX, there will be a problem also. The problem is it can't find mysql home. To fix that, open Rakefile in do/do_mysql/ and change these codes below  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;task &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;install&lt;/span&gt; =&amp;gt; [ &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;package&lt;/span&gt; ] &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
  sh &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;StringVariable&quot;&gt;SUDO&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; gem install --local pkg/&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;spec&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt;-&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;spec&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;version&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; --no-update-sources&lt;span class=&quot;String&quot;&gt;}&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;verbose&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;to  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;task &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;install&lt;/span&gt; =&amp;gt; [ &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;package&lt;/span&gt; ] &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
  sh &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;StringVariable&quot;&gt;SUDO&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; gem install --local pkg/&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;spec&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt;-&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;spec&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;version&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; --no-update-sources -- --with-mysql-dir=/usr/local/mysql&lt;span class=&quot;String&quot;&gt;}&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;verbose&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;add &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;-- --with-mysql-dir=/usr/local/mysql  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After you install all gems on your machine, you will have a lot of gems. Just upload all gems to your home on DH and install them.  &lt;/p&gt;

&lt;p&gt;I have had problems with Dreamhost's shared gems conflicting with gems that you install locally. To fix that, open ~/.bashrc and change $GEM_PATH to  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;export GEM_PATH=&quot;$GEM_HOME&quot;&lt;/pre&gt;  

&lt;h3&gt;Merb app configuration&lt;/h3&gt;

&lt;p&gt;create config.ru to your home app  &lt;/p&gt;

&lt;blockquote&gt;
    &lt;ul&gt;
    &lt;li&gt;app
    &lt;ul&gt;
    &lt;li&gt;...  &lt;/li&gt;
    &lt;li&gt;public  &lt;/li&gt;
    &lt;li&gt;config.ru &amp;lt;&amp;lt; add it  &lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;and put these codes below to config.ru  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  7&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  8&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  9&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 10&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 11&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 12&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 13&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 14&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 15&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 16&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 17&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 18&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 19&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 20&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 21&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 22&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 23&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 24&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 25&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 26&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 27&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 28&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 29&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; config.ru&lt;/span&gt;

&lt;span class=&quot;Variable&quot;&gt;ENV&lt;/span&gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;GEM_PATH&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;] &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;/home/your_home/.gems/&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; your local gem home&lt;/span&gt;

&lt;span class=&quot;Keyword&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;rubygems&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; There were a few problems on loading merb-core at the firt time after Passenger pid has been killed. These codes below were added to fix.&lt;/span&gt;
[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/abstract-1.0.0/bin&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/abstract-1.0.0/lib&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/erubis-2.6.2/bin&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/erubis-2.6.2/lib&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/json_pure-1.1.3/bin&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/json_pure-1.1.3/lib&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/rspec-1.1.4/bin&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/rspec-1.1.4/lib&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/mime-types-1.15/bin&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/mime-types-1.15/lib&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/merb-core-0.9.4/bin&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, 
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/home/your_name/.gems/gems/merb-core-0.9.4/lib&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;].&lt;span class=&quot;Entity&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;path&lt;/span&gt;|
  &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;LOAD_PATH&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; path
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;merb-core&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;Support&quot;&gt;Merb&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Config&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;setup&lt;/span&gt;(&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;merb_root&lt;/span&gt;   =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;.&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
                   &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;environment&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Variable&quot;&gt;ENV&lt;/span&gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;RACK_ENV&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;])
&lt;span class=&quot;Support&quot;&gt;Merb&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;environment&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;Merb&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Config&lt;/span&gt;[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;environment&lt;/span&gt;]
&lt;span class=&quot;Support&quot;&gt;Merb&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;Merb&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Config&lt;/span&gt;[&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;merb_root&lt;/span&gt;]
&lt;span class=&quot;Support&quot;&gt;Merb&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;BootLoader&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;run&lt;/span&gt;

run &lt;span class=&quot;Support&quot;&gt;Merb&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Rack&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Application&lt;/span&gt;.&lt;span class=&quot;Keyword&quot;&gt;new&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;and  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ touch tmp/restart.txt&lt;/pre&gt;  

&lt;p&gt;for restarting  &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://snbc.punneng.net&quot;&gt;Example&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Thanks again:&lt;br /&gt;
&lt;a href=&quot;http://www.nateclark.com/articles/2006/10/20/dreamhost-your-own-packages-and-gems&quot;&gt;nateclark&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://merb.4ninjas.org/&quot;&gt;4 ninjas&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://wiki.merbivore.com/pages/phusion-passenger&quot;&gt;Merb's wiki&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-07-27:1014</id>
    <published>2008-07-27T16:43:00Z</published>
    <updated>2008-07-27T16:47:10Z</updated>
    <category term="General"/>
    <link href="http://weblog.punneng.net/2008/7/27/adding-svn-repos-to-github" rel="alternate" type="text/html"/>
    <title>Adding svn repos to github</title>
<content type="html">
            &lt;p&gt;ช่วงนี้กำลังต่อสู้กับ git อยู่ครับ แล้วก็ยังมึนๆ กับมันอยู่ ยังไม่ค่อยเข้าใจอะไรกับมันมาก&lt;br /&gt;
แล้วยังกระแดะจะให้มันมาใช้คู่กับ svn อีก ก็ Capistrano บน Dreamhost มันใช้ได้แค่ svn นี่หว่า ก็มาลุยกัน  &lt;/p&gt;

&lt;p&gt;สมมติว่าติดตั้ง git-svn ไปแล้ว&lt;br /&gt;
ก็ clone repo ก่อน  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ git svn clone http://svn.yoursite.com/your_project --trunk=trunk&lt;/pre&gt;  

มันก็จะ init ค่าต่างๆ ใน .git/config สำหรับ svn ให้  
แล้วไป init ค่าสำหรับ github  

&lt;pre class=&quot;terminal&quot;&gt;$ git remote add origin git@github.com:YourUsername/your_project.git
$ git push origin master&lt;/pre&gt;  

ก็ลองดูใน .git/config ดูนะครับ ว่ามัน config อะไรเพิ่มไป  
ใส่เพิ่มว่า  

&lt;pre class=&quot;terminal&quot;&gt;[branch &quot;master&quot;]
    remote = origin
    merge = refs/heads/master
&lt;/pre&gt;  

&lt;p&gt;แล้วก็แก้งานไป ตามปกติ แล้วลอง  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ git status
$ git add .
$ git commit -m &quot;your comment&quot;&lt;/pre&gt;  

&lt;p&gt;ณ ตรงนี้ มันจะไปแก้ refs/head/master เป็นค่าๆ นึง ซึ่งเป็นค่าใหม่&lt;br /&gt;
ถ้า push จะปกติดี&lt;br /&gt;
แต่ปัญหามันอยู่ที่ ถ้า  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ git svn dcommit&lt;/pre&gt;  

&lt;p&gt;ไปก่อน มันก็จะไปจัดการในส่วนของ svn ให้ แต่มันจะไปแก้ refs/head/master เป็นอีกค่านึง(ต่อจากอันเก่า)&lt;br /&gt;
พอสั่ง push คราวนี้ จะไม่ได้แล้ว มันจะขึ้นว่า  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;error: remote 'refs/heads/master' is not a strict subset of local ref 'refs/heads/master'. maybe you are not up-to-date and need to pull first?&lt;/pre&gt;  

&lt;p&gt;อันนี้ เป็นสิ่งที่ยังงงอยู่ ผมเข้าใจว่า ค่าเก่า(ก่อน commit) กับค่าใหม่(หลัง commit) มีอะไรเชื่อมกันอยู่ ถ้า push ก็จะได้ปกติ&lt;br /&gt;
แต่ถ้า dcommit แล้ว push มันคงเอาค่าเก่า(ก่อน commit ค่านี้จะอยู่บน github ด้วย) มาทำอะไรกับค่าใหม่กว่า(หลัง dcommit) สิ่งที่เชื่อมกันอยู่ คงจะไม่ถูกต้อง เพราะมันเหมือนกระโดดไปสอง step ใครก็ได้ กรุณาช่วยหาคำตอบให้ผมหน่อยนะครับ ขอบคุณล่วงหน้าครับ อุอุ   &lt;/p&gt;

&lt;p&gt;วิธีซ่อมคือ  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ git pull origin master&lt;/pre&gt;  

&lt;p&gt;เป็นอันเสร็จพิธี  &lt;/p&gt;

&lt;p&gt;ถ้า push ก่อน แล้ว dcommit มันจะตรวจว่ามีการแก้ล่าสุดหรือเปล่า กรณี้นี้ ไม่มีการแก้ไขล่าสุด มันจะ reset refs/heads/master เป็นตัวเก่า เลยปกติ&lt;br /&gt;
เพราะฉะนั้น ก็ push ก่อน dcommit ละกัน&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-07-13:1011</id>
    <published>2008-07-13T08:50:00Z</published>
    <updated>2008-07-13T09:01:49Z</updated>
    <category term="Merb"/>
    <link href="http://weblog.punneng.net/2008/7/13/installing-merb" rel="alternate" type="text/html"/>
    <title>Installing Merb </title>
<content type="html">
            &lt;p&gt;เกริ่นก่อนนิดนึง อะไรคือ Merb??  &lt;/p&gt;

&lt;p&gt;Merb ก็เป็น MVC Framework เช่นเดียวกับ Ruby on Rails เพียงแต่มันสามารถกำหนดฝั่ง View และ Model เองได้ แต่เห็นจะเน้นไปที่ฝั่ง Model มากกว่า สามสิ่งที่นิยมใช้กับฝั่ง Model ก็คือ &lt;a href=&quot;http://ar.rubyonrails.org/&quot;&gt;ActiveRecore&lt;/a&gt;, &lt;a href=&quot;http://datamapper.org/&quot;&gt;DataMapper&lt;/a&gt; และ &lt;a href=&quot;http://sequel.rubyforge.org/&quot;&gt;Sequel&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;นั่นหมายความว่า เราสามารถจะเอาไอ้นั่น ไอ้นี่ มาปะติดปะต่อเองได้ เรื่องของเรื่องคือ Ruby on Rails มันช้า magic มันเยอะ บางคนไม่ชอบ magic เพราะมันเกินความจำเป็น(แต่ผมชอบ) ถ้าตัดออกได้ หรือเปลี่ยนได้ ก็น่าจะดีกว่า กอปรกับความเทอะทะของ Rails เอง ทีมที่พัฒนา Merb ก็เลยจัดการเขียนใหม่ซะ  &lt;/p&gt;

&lt;p&gt;จุดเด่นโดยรวมของ Merb ก็คือ เรื่องความเร็ว(ที่ดีกว่า Rails) และการเลือกใช้ฝั่ง View และ Model เองได้(ผมเลือก DataMapper)  &lt;/p&gt;

&lt;p&gt;มาเริ่มติดตั้งกัน&lt;br /&gt;
ผมจะติ๊งต่างว่าทุกท่านที่เข้ามาอ่านใน blog ผม คงจะเคยติดตั้ง Rails กันมาบ้างแล้ว และสิ่งหนึ่งที่จำเป็นต้องมีคือ RubyGems ดังนั้น ผมจึงข้ามเรื่องการติดตั้ง RubyGems ไป  &lt;/p&gt;

&lt;p&gt;ก่อนที่จะติดตั้งได้สมบูรณ์ ก็ลองผิดลองถูกมานาน จนได้สูตรสำเร็จว่า update มันใหม่ให้หมด ก็ติดตั้งได้เอง ก็เริ่มด้วยการ upgrade RubyGems ละกัน  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ sudo gem update --system&lt;/pre&gt;  

&lt;p&gt;และ Ruby(1.8.6 เป็นอย่างต่ำ)&lt;br /&gt;
วิธีการ upgrate ขึ้นอยู่กับแต่ละท่านครับ บางคน apt-get บางคน MacPorts หรือบางคนก็ compile เองแม่งเลย  &lt;/p&gt;

&lt;p&gt;สิ่งต่อไปที่ต้องมีคือ Git&lt;br /&gt;
บน Ubuntu  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ sudo apt-get install git&lt;/pre&gt;  

&lt;p&gt;บน OSX Leopard   &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://solutions.treypiepmeier.com/2008/02/25/installing-git-on-os-x-leopard/&quot;&gt;Installing Git on OS X Leopard&lt;/a&gt;(MacPorts)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://subtlegradient.com/articles/2008/02/21/install_git_leopard&quot;&gt;Simple Install of Git on Leopard&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;บน OSX Tiger  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://larrytheliquid.com/2007/12/29/compiling-git-and-git-svn-on-osx-tiger/&quot;&gt;Compiling Git and git-svn on OSX Tiger&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ก่อนจัดการกับ Merb ก็ติดตั้งพวก gem dependency ก่อน  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ sudo gem install rack mongrel json erubis mime-types rspec hpricot mocha rubigen haml markaby mailfactory ruby2ruby&lt;/pre&gt;  

&lt;p&gt;จากนั้น clone Merb มาด้วย  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ git clone git://github.com/wycats/merb-core.git
$ git clone git://github.com/wycats/merb-plugins.git
$ git clone git://github.com/wycats/merb-more.git&lt;/pre&gt;  

&lt;p&gt;แล้วก็ติดตั้ง  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ cd merb-core ; rake install ; cd ..    
$ cd merb-more ; rake install ; cd ..
$ cd merb-plugins; rake install ; cd ..&lt;/pre&gt;  

&lt;p&gt;ฝั่ง Model ผมเลือก DataMapper เพราะหน้าตาคล้ายกับ ActiveRecord แต่เบากว่า  &lt;/p&gt;

&lt;p&gt;clone driver ก่อน&lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ git clone git://github.com/sam/extlib.git  
$ git clone git://github.com/sam/do.git&lt;/pre&gt;  

&lt;p&gt;แล้วก็ติดตั้ง  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ cd extlib ; rake install ; cd ..
$ cd do 
$ cd data_objects ; rake install ; cd ..
$ cd do_mysql  # || do_postgres || do_sqlite3
$ rake install&lt;/pre&gt;  

&lt;p&gt;ผมเลือก mysql  &lt;/p&gt;

&lt;p&gt;ขั้นตอนนี้จะมีปัญหานิดหน่อย ขณะที่ติดตั้ง do_mysql&lt;br /&gt;
บน Ubuntu ถ้าหากใช้ mysql ที่ติดตั้งเอง แล้ว home directory มันไม่อยู่ที่ default path มันจะมองหา mysql home ไม่เจอ และอีกปัญหานึงคือ มันจะหา mysql.h ไม่เจอ วิธีซ่อมคือ  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ sudo apt-get install mysql&lt;/pre&gt;  

&lt;p&gt;และ libmysqlclient15 สำหรับ myslq.h มันจะไปอยู่ใน /usr/include/mysql  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ sudo apt-get install libmysqlclient15-dev&lt;/pre&gt; 

&lt;p&gt;สำหรับ OSX ก็เหมือนกัน มันจะหา home directory ไม่เจอ ผมแนะนำให้โหลดจากเว็บมันเลย ที่&lt;a href=&quot;http://dev.mysql.com/downloads/mysql/5.0.html#macosx-dmg&quot;&gt;หน้า download&lt;/a&gt; อันนี้มี mysql.h มาให้ด้วย&lt;br /&gt;
มันยังไม่ใช่แค่นี้ ต้องไปใช้กำลังกันหน่อย&lt;br /&gt;
ตอนติดตั้ง mysql ไอ้ home directory มันจะไปอยู่ที่ /usr/local/mysql&lt;br /&gt;
ก็ต้องไประบุเพิ่มนิดนึงใน Rakefile ของ do_mysql จะมี  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;task &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;install&lt;/span&gt; =&amp;gt; [ &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;package&lt;/span&gt; ] &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
  sh &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;StringVariable&quot;&gt;SUDO&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; gem install --local pkg/&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;spec&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt;-&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;spec&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;version&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; --no-update-sources&lt;span class=&quot;String&quot;&gt;}&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;verbose&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;ให้เพิ่ม -- --with-mysql-dir=/usr/local/mysql ไปด้วย เป็น  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;task &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;install&lt;/span&gt; =&amp;gt; [ &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;package&lt;/span&gt; ] &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
  sh &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;StringVariable&quot;&gt;SUDO&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; gem install --local pkg/&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;spec&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;name&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt;-&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;spec&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;version&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; --no-update-sources -- --with-mysql-dir=/usr/local/mysql&lt;span class=&quot;String&quot;&gt;}&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;verbose&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;ยังไม่จบครับ clone ตัว DataMapper กันต่อ  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;git clone git://github.com/sam/dm-core.git
git clone git://github.com/sam/dm-more.git&lt;/pre&gt;  

&lt;p&gt;แล้วก็ติดตั้ง  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ cd dm-core ; rake install ; cd ..
$ cd dm-more ; rake install&lt;/pre&gt;  

&lt;p&gt;เท่านี้น่าจะเสร็จสิ้น ลองแบบง่ายๆ  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ merb-gen app your_project_name
$ cd your_project_name
$ merb&lt;/pre&gt;  

&lt;p&gt;ก็น่าจะทำงานได้ปกติ ถ้าไม่ปกติ ก็ลง comment หรือ error ไว้ได้ครับ จะช่วย debug  &lt;/p&gt;

&lt;p&gt;ปล. ยังมีตอนต่อไปอีกหลายตอนครับ&lt;br /&gt;
ปอ. สำหรับบน Windows ไปเอาตัวรอดกันเองนะครับ =='  &lt;/p&gt;

&lt;p&gt;ข้อมูลจาก &lt;a href=&quot;http://merb.4ninjas.org/&quot;&gt;merb.4ninjas&lt;/a&gt;  &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-07-05:1010</id>
    <published>2008-07-05T13:33:00Z</published>
    <updated>2008-07-05T13:34:31Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.net/2008/7/5/modifying-fieldwitherrors" rel="alternate" type="text/html"/>
    <title>Modifying fieldWithErrors</title>
<content type="html">
            &lt;p&gt;fieldWithErrors เนี่ย บางทีมันก็มีประโยชน์ดีนะ แต่บางทีก็อยากจะเอาออก หรืออยากจะแก้ไข  &lt;/p&gt;

&lt;p&gt;เอาแบบนี้ดีกว่า  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  7&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  8&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  9&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 10&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 11&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Support&quot;&gt;ActionView&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;field_error_proc&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;Proc&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;html_tag&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;instance&lt;/span&gt;|          
  &lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; html_tag &lt;span class=&quot;Keyword&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringRegexp&quot;&gt;&amp;lt;label.*&amp;gt;.*&amp;lt;&lt;span class=&quot;StringRegexpSpecial&quot;&gt;\/&lt;/span&gt;label&amp;gt;&lt;/span&gt;&lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;/&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&amp;lt;div class=&lt;span class=&quot;StringConstant&quot;&gt;\&amp;quot;&lt;/span&gt;labelWithErrors&lt;span class=&quot;StringConstant&quot;&gt;\&amp;quot;&lt;/span&gt;&amp;gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;html_tag&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&amp;lt;/div&amp;gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; 
  &lt;span class=&quot;Keyword&quot;&gt;elsif&lt;/span&gt; html_tag &lt;span class=&quot;Keyword&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringRegexp&quot;&gt;terms_and_conditions&lt;/span&gt;&lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;/&lt;/span&gt;&lt;/span&gt;   
    &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&amp;lt;div class=&lt;span class=&quot;StringConstant&quot;&gt;\&amp;quot;&lt;/span&gt;tickWithErrors&lt;span class=&quot;StringConstant&quot;&gt;\&amp;quot;&lt;/span&gt;&amp;gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;html_tag&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&amp;lt;/div&amp;gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;elsif&lt;/span&gt; html_tag &lt;span class=&quot;Keyword&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringRegexp&quot;&gt;radio&lt;/span&gt;&lt;span class=&quot;StringRegexp&quot;&gt;&lt;span class=&quot;StringRegexp&quot;&gt;/&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&amp;lt;div class=&lt;span class=&quot;StringConstant&quot;&gt;\&amp;quot;&lt;/span&gt;radioWithErrors&lt;span class=&quot;StringConstant&quot;&gt;\&amp;quot;&lt;/span&gt;&amp;gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;html_tag&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&amp;lt;/div&amp;gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;     
  &lt;span class=&quot;Keyword&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&amp;lt;div class=&lt;span class=&quot;StringConstant&quot;&gt;\&amp;quot;&lt;/span&gt;fieldWithErrors&lt;span class=&quot;StringConstant&quot;&gt;\&amp;quot;&lt;/span&gt;&amp;gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;html_tag&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&amp;lt;/div&amp;gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;      
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;                            
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;ใส่ไปใน environment.rb&lt;br /&gt;
ใครมีความคิดอะไรก็ใส่ไปให้หมด สำหรับผมการ filter ง่ายๆ ก็ใช้ RegExp ครับ  &lt;/p&gt;

&lt;p&gt;ไม่มีกะจิตกะใจจะเขียนเท่าไหร่ กำลังทะเลาะกับ Merb อยู่ ทำไมมันติดตั้งยากเยี่ยงนี้ !!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-06-28:1009</id>
    <published>2008-06-28T20:00:00Z</published>
    <updated>2008-06-28T20:02:18Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.net/2008/6/28/ruby-on-rails-customize-form-helper" rel="alternate" type="text/html"/>
    <title>Ruby on Rails :: Customize Form helper</title>
<content type="html">
            &lt;p&gt;เพิ่งทำของเล่นเสร็จไปตัวนึง เลยไม่ได้เขียน blog  &lt;/p&gt;

&lt;p&gt;ไม่ต้องพล่ามมาก เอาเลยดีกว่า  &lt;/p&gt;

&lt;p&gt;ใน Rails มี Form helper อยู่ เราทำอะไรกับมันได้บ้าง?? ลองดูแบบนี้ก่อน&lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%&lt;/span&gt; form_for &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;person&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;person&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;url&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt; &lt;/span&gt;&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;action&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;update&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
  First name: &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; f&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;text_field&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;first_name&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
  Last name : &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; f&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;text_field&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;last_name&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
  Biography : &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; text_area &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;person&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;biography&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
  Admin?    : &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; check_box_tag &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;person[admin]&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;person&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;company&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;admin?&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&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;ปกติ ผมจะต้องใส่ label ให้มันด้วย&lt;br /&gt;
ผมไม่ค่อยชอบเลย ผมอยากได้  &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;f.text_field :first_name  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;แล้วมันใส่ label ไปให้ผมเลย&lt;br /&gt;
มันทำได้โดยสร้าง module เพิ่ม ไปใว้ใน config/initializers/ (มันมาตอน rails 2.0 ออกมั้ง ทุก file ในนี้ จะถูกโหลดโดยอัติโนมัติ)  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;JEntityNameType&quot;&gt;MyFormHelper&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;JEntityNameType&quot;&gt;MyFormBuilder&lt;span class=&quot;EntityInheritedClass&quot;&gt; &lt;span class=&quot;EntityInheritedClass&quot;&gt;&amp;lt;&lt;/span&gt; ActionView::Helpers::FormBuilder&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;text_field&lt;/span&gt;(&lt;span class=&quot;Variable&quot;&gt;method&lt;span class=&quot;Variable&quot;&gt;,&lt;/span&gt; options &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;}&lt;/span&gt;&lt;/span&gt;)
      &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;template&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;content_tag&lt;/span&gt;(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;p&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Entity&quot;&gt;label&lt;/span&gt;(method) &lt;span class=&quot;Keyword&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;&amp;lt;&lt;/span&gt;br &lt;span class=&quot;Keyword&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;super&lt;/span&gt;)
    &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;ก็ extends ตามเรื่องไป(ต้องใช้พลังแงะนิดหน่อย)  &lt;/p&gt;

&lt;p&gt;ใน form ด้านบน ก็เพิ่ม :builder =&gt; MyFormHelper::MyFormBuilder&lt;br /&gt;
หน้าตาจะเป็นแบบนี้  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%&lt;/span&gt; form_for &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;person&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;person&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;url&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt; &lt;/span&gt;&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;action&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;update&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;builder&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;MyFormHelper&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;MyFormBuilder&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; f&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;text_field&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;first_name&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; f&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;text_field&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;last_name&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; text_area &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;person&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;biography&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; check_box_tag &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;person[admin]&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;person&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;company&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;admin?&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&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;แล้วผมก็จะได้ผลของการ render text_field เป็นแบบนี้&lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;for&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;person_first_name&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;First name&lt;span class=&quot;MetaTagInline&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;br&lt;/span&gt; /&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;MetaTagInline&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;text&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;MetaTagInline&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;person_first_name&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;MetaTagInline&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;person[first_name]&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&amp;lt;/&lt;span class=&quot;MetaTagInline&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;MetaTagInline&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;อะไรประมาณนี้  &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-06-06:1003</id>
    <published>2008-06-06T09:59:00Z</published>
    <updated>2008-06-06T10:28:02Z</updated>
    <category term="General"/>
    <link href="http://weblog.punneng.net/2008/6/6/inverse-captcha" rel="alternate" type="text/html"/>
    <title>Inverse Captcha</title>
<content type="html">
            &lt;p&gt;ดีใจมากครับ ในที่สุด blog ผมก็หมดปัญหาเรื่อง spam ไปเสียที เย้..  &lt;/p&gt;

&lt;p&gt;ทีแรกก็ใช้ akismet ก็ดีอยู่แล้ว แต่มันก็แสดงว่ามีอะไรเป็น spam บ้าง มันขัดหูขัดตามผมเหลือเกิน จนคิดว่าต้องใช้ captcha ช่วยละ  &lt;/p&gt;

&lt;p&gt;หลังจากการ search หา plugin ดูใน google ตัวแรกที่เจอคือ &lt;a href=&quot;http://www.artweb-design.de/2007/9/25/inverse-captcha-anti-comment-spam-technique-now-a-regular-mephisto-plugin&quot;&gt;Inverse Captcha&lt;/a&gt; ครับ แค่ชื่อก็น่างงแล้ว   &lt;/p&gt;

&lt;p&gt;แต่หลังจากใช้ไป 1 อาทิตย์ ไม่มี spam หลุดมาสักตัว(ใน  blog ของ &lt;a href=&quot;http://www.artweb-design.de/2007/5/8/report-30-days-with-no-blog-spam-on-mephisto&quot;&gt;Sven Fuchs&lt;/a&gt; เอง  เขาก็ทดลองเดือนนึง)  ไม่ต้องมี captcha แปะให้น่ารำคาญ ไม่ต้องเพ่งตัวอักษรที่อ่านยากแสนยาก  &lt;/p&gt;

&lt;p&gt;หลังจากที่ลองเล่นดูแล้ว ก็ได้ความว่า  &lt;/p&gt;

&lt;p&gt;ในหน้า post ลอง view source แถวๆ กล่อง comment จะมี input ประมาณนี้  &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;comment[author]&lt;br /&gt;
    comment[author_email]&lt;br /&gt;
    comment[author_url]&lt;br /&gt;
    comment[body]  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;แต่หลังจากที่เอาไอ้ inverse captcha นี้มาใส่ หน้าตาจะกลายเป็นแบบนี้  &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;comment[author]&lt;br /&gt;
    comment[author_xxxxxx]&lt;br /&gt;
    comment[author_url]&lt;br /&gt;
    comment[body]&lt;br /&gt;
    comment[author_email] #display:none;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;สิ่งที่เปลี่ยนไปคือ จะมี author_xxxxxx ซึ่ง xxxxxx นี้ จะถูก generate มาอีกที จะเรียกว่า random key ละกัน&lt;br /&gt;
แล้วตรงส่วนของช่อง email ปกติ ก็จะถูก display:none ไว้&lt;br /&gt;
อธิบายได้ว่า ถ้าเป็นคน จะมองไม่เห็นช่องนี้ แล้วก็จะไม่ใส่&lt;br /&gt;
แต่ถ้าเป็น bot มันจะ post email มาแน่นอน&lt;br /&gt;
ทำให้รู้ว่า ถ้าหากใส่ email มา แสดงว่าไม่ใช่คนแน่นอน  &lt;/p&gt;

&lt;p&gt;สำหรับตัว random key ก็จะถูก generate มา 
ใน plugin ของ mephisto ที่ผมใช้อยู่ ดูเหมือนจะยังไม่ใช่สิ่งที่ผมต้องการเป๊ะๆ&lt;br /&gt;
เพราะการ refresh 1 ครั้ง ตัว random key น่าจะเปลี่ยนไป แต่หลังจากลองงัดแงะดูแล้ว ดูเหมือนว่าจะมีปัญหากับ liquid template เลยไม่สามารถจัดการตรงนี้ได้ ยังไงจะลอง implement ให้ดูละกันครับ เพราะผมว่าตัว random key น่าจะเปลี่ยนไปทุกครั้งที่มีการ refresh หน้าเว็บ  &lt;/p&gt;

&lt;p&gt;ถ้า random key เหมือนเดิมทุกครั้ง bot อาจจะฉลาด แต่ถ้ามันเปลี่ยนไปทุกครั้ง bot คงไม่ฉลาดขนาดนั้นมั้งครับ  &lt;/p&gt;

&lt;p&gt;สรุปอีกที แนวคิดนี้ แค่เพิ่ม input มาตัวนึง แล้วเอาตัวปกติซ่อนไว้ ถ้าเป็นคน จะมองไม่เห็น แต่จะเห็นช่องที่ถูกเพิ่มมา เราก็จะสามารถเขียนตรวจได้ว่า ถ้ามี post จาก email ปกติมา นั่นแหละ คือ spam แต่ถ้ามาจากช่องที่ถูกเพิ่ม มันคือคน  &lt;/p&gt;

&lt;p&gt;ผมค่อนข้างประทับใจกับแนวคิดนี้ครับ มันง่ายดี กระบวณการ post ก็ยังเหมือนเดิม  &lt;/p&gt;

&lt;p&gt;ว่าแต่มัน inverse ยังไงเนี่ย =='&lt;/p&gt;

&lt;p&gt;ปล. เดี๋ยวจะ implement ให้ดูอีกทีครับ จะได้เข้าใจในเชิงลึกอีกที&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-05-27:1000</id>
    <published>2008-05-27T19:46:00Z</published>
    <updated>2008-05-27T19:47:21Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.net/2008/5/27/railsdb" rel="alternate" type="text/html"/>
    <title>RailsDB</title>
<content type="html">
            &lt;p&gt;ทุกชิ้นงาน(ของออฟฟิศ)ที่ผมทำบน rails อยู่ทุกวันนี้ host ด้วย vps ครับ แล้วตอนติดตั้ง ก็ขี้เกียจติดตั้งชุดแปล php ด้วย ผมเลยอยากได้อะไรเหมือน phpmyadmin ครับ&lt;br /&gt;
ทางเลือกแรก ต้องใช้ edge rails&lt;br /&gt;
มีตัวช่วยใหม่ ชื่อว่า &lt;a href=&quot;http://ryandaigle.com/articles/2008/5/13/what-s-new-in-edge-rails-db-console&quot;&gt;dbconsole&lt;/a&gt; แต่ก็ยังเป็น command line แค่มัน remote ให้ แค่นั้นเอง&lt;br /&gt;
ทางเลือกที่สองก็คือ &lt;a href=&quot;http://railsdb.org/&quot;&gt;RailsDB&lt;/a&gt;&lt;br /&gt;
ทางเลือกที่สาม เอ่อ.. ช่วย comment บอกที  &lt;/p&gt;

&lt;p&gt;ย้อนกลับมาที่ RailsDB ครับ น่าจะใช้แทน phpmyadmin ได้มากที่สุด คืนนี้ ผมก็เลยลองซะ ผลที่ได้คือ error!!(เป็นปกติ)  &lt;/p&gt;

&lt;p&gt;มันพังเพราะ default config มันผิด ตอนต่อ db หน้าตาประมาณนี้  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  7&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  8&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  9&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 10&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 11&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 12&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 13&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 14&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 15&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 16&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 17&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 18&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 19&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 20&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 21&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 22&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 23&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 24&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt; 25&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;switch_db&lt;/span&gt;(&lt;span class=&quot;Variable&quot;&gt; database &lt;/span&gt;)     
    &lt;span class=&quot;Keyword&quot;&gt;case&lt;/span&gt; database.&lt;span class=&quot;Entity&quot;&gt;driver&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;name&lt;/span&gt;
      &lt;span class=&quot;Keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;sqlite3&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;Support&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;establish_connection&lt;/span&gt;(
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;adapter&lt;/span&gt;  =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;sqlite3&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;,
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;database&lt;/span&gt; =&amp;gt; database.&lt;span class=&quot;Entity&quot;&gt;path&lt;/span&gt;
        )
      &lt;span class=&quot;Keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;mysql&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;Support&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;establish_connection&lt;/span&gt;(
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;adapter&lt;/span&gt;  =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;mysql&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;,
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;database&lt;/span&gt; =&amp;gt; database.&lt;span class=&quot;Entity&quot;&gt;name&lt;/span&gt;,
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;host&lt;/span&gt;     =&amp;gt; database.&lt;span class=&quot;Entity&quot;&gt;host&lt;/span&gt;,
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;username&lt;/span&gt; =&amp;gt; database.&lt;span class=&quot;Entity&quot;&gt;username&lt;/span&gt;,
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;password&lt;/span&gt; =&amp;gt; database.&lt;span class=&quot;Entity&quot;&gt;password&lt;/span&gt;
        )
      &lt;span class=&quot;Keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;postgresql&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;Support&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Base&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;establish_connection&lt;/span&gt;(
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;adapter&lt;/span&gt;  =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;postgresql&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;,
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;database&lt;/span&gt; =&amp;gt; database.&lt;span class=&quot;Entity&quot;&gt;name&lt;/span&gt;,
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;host&lt;/span&gt;     =&amp;gt; database.&lt;span class=&quot;Entity&quot;&gt;host&lt;/span&gt;,
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;username&lt;/span&gt; =&amp;gt; database.&lt;span class=&quot;Entity&quot;&gt;username&lt;/span&gt;,
          &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;password&lt;/span&gt; =&amp;gt; database.&lt;span class=&quot;Entity&quot;&gt;password&lt;/span&gt;
        )
    &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;code ชุดนี้ อยู่ที่ app/models/switch.rb ครับ&lt;br /&gt;
สังเกตได้ว่า มันไม่มี port หรือ socket ให้กรอกครับ ค่า default ของ mysql ใน activerecord เองก็กำหนดไว้ว่า port เป็น 3306 และ socket เป็น /tmp/mysql.sock  &lt;/p&gt;

&lt;p&gt;วิธีซ่อมก็ง่ายๆ ครับ ใส่่ port หรือ socket ที่ถูกต้องเข้าไป  &lt;/p&gt;

&lt;p&gt;ประชาสัมพันธ์หน่อยครับ&lt;br /&gt;
มีงาน train (J)Ruby on Rails ของ narisa นะครับ ใครสนใจก็ตาม link ข้างล่างเลย&lt;br /&gt;
&lt;a href=&quot;http://www.narisa.com/forums/index.php?showtopic=23552&quot;&gt;วันจัด train เรื่อง (J)Ruby On Rails ครับ - Narisa.com&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-05-11:898</id>
    <published>2008-05-11T09:18:00Z</published>
    <updated>2008-05-12T03:17:51Z</updated>
    <category term="General"/>
    <link href="http://weblog.punneng.net/2008/5/11/gedit-looks-like-textmate" rel="alternate" type="text/html"/>
    <title>GEdit looks like Textmate</title>
<content type="html">
            &lt;p&gt;Textmate is the best text editor I've ever used. Unfortunately, it's only on Mac OS X. As you guys know I'm a big fan of Ubuntu and I prefer GEdit.  &lt;/p&gt;

&lt;p&gt;One thing I really like on Mac OS X is font rendering and that is what I like when I'm on Textmate, it looks pretty cool so I'd like to see it in GEdit as well !!!&lt;/p&gt;

&lt;p&gt;I knew how to do that from &lt;a href=&quot;http://gotoknow.org/profile/tonkla&quot;&gt;Tonkla&lt;/a&gt;(thanks a lot). That's bloody easy, just open terminal and put&lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;$ sudo dpkg-reconfigure fontconfig-config&lt;/pre&gt;  

&lt;p&gt;and then set font hinting to &lt;strong&gt;&amp;quot;None&amp;quot;&lt;/strong&gt; and leave the rest of the options as default.  &lt;/p&gt;

&lt;p&gt;Install font you prefer(I prefer Monaco) then you'll get your GEdit looks like this:  &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/punneng/2482764458/&quot; title=&quot;GEdit looks like Textmate&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3252/2482764458_62beed693f.jpg&quot; height=&quot;406&quot; alt=&quot;GEdit looks like Textmate&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-04-25:832</id>
    <published>2008-04-25T19:38:00Z</published>
    <updated>2008-04-25T19:40:59Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.net/2008/4/25/better-error-messages-for-validation" rel="alternate" type="text/html"/>
    <title>Better error messages for validation</title>
<content type="html">
            &lt;p&gt;แว่บๆ ไปอ่าน feed เจอของ &lt;a href=&quot;http://www.softiesonrails.com/2008/4/23/better-messages-for-activerecord-validation-errors&quot;&gt;Softies on Rails&lt;/a&gt;&lt;br /&gt;
error_messages_for เปลี่ยนไป(ตอนไหนไม่รู้)&lt;br /&gt;
ที่เคยเขียนไป&lt;a href=&quot;http://weblog.punneng.net/2007/4/2/ruby-on-rails-customized-validation&quot;&gt;ของเก่า&lt;/a&gt; จำได้ว่ามันแก้ header_messages ไม่ได้ เลยต้องแก้เอง เพราะหน้าตาใน helper ของเก่าเป็นแบบนี้  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;header_message &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;Entity&quot;&gt;pluralize&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;(&lt;/span&gt;count&lt;span class=&quot;StringEmbeddedSource&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;error&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; prohibited this &lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;(&lt;/span&gt;options&lt;span class=&quot;StringEmbeddedSource&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;StringConstant&quot;&gt;&lt;span class=&quot;StringConstant&quot;&gt;:&lt;/span&gt;object_name&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;||&lt;/span&gt; params&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;first&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;to_s&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Entity&quot;&gt;gsub&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;_&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;StringEmbeddedSource&quot;&gt;}&lt;/span&gt;&lt;/span&gt; from being saved&lt;span class=&quot;String&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;แว่บไปดูใน &lt;a href=&quot;http://api.rubyonrails.org&quot;&gt;API&lt;/a&gt; ไปเจอว่าเปลี่ยนไปจริงๆ ได้ของแถมมาอีก คือ error_messages_on ซึ่งผมไม่เคยใช้มาก่อน(บ้านนอก)  &lt;/p&gt;

&lt;p&gt;list ข้างล่างคือค่า params ที่เราจะใส่ไปได้ใน error_messages_for    &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;header_tag ค่า default เป็น h2  &lt;/li&gt;
&lt;li&gt;id ค่า default เป็น errorExplanation  &lt;/li&gt;
&lt;li&gt;class ค่า default เป็น errorExplanation  &lt;/li&gt;
&lt;li&gt;object ไว้เซ็ตค่ากรณีที่ไม่มี object ที่ต้องใส่ตาม convention เช่น  &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
    &lt;p&gt;error_messages_for 'user'  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ถ้าจะให้ขึ้น ฝั่ง view จะต้องมองเห็น @user แล้ว error ถึงจะออก&lt;br /&gt;
แต่แบบใหม่นี่ สามารถอ้างได้จาก object อื่นได้เลย เช่น  &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;error_messages_for 'user', @question.user  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;object_name ตรงตัว ถ้าไม่ใส่ จะไปใช้ object แทน ในตัวอย่างคือ User  &lt;/li&gt;
&lt;li&gt;header_message ตรงตัว ค่า default เป็น X errors prohibited this object from being saved ซึ่ง X ก็คือ object_name นั่นแหละ  &lt;/li&gt;
&lt;li&gt;message คือข้อความที่อยู่ใต้ header_message และมาก่อน error list ค่า default เป็น There were problems with the following fields:  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ถัดมาก็ error_message_on&lt;br /&gt;
ไม่มีอะไรง่ายกว่าการดูตัวอย่าง  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  5&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  6&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  7&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; error_message_on &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;post&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;title&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt; =&amp;gt;
&lt;span class=&quot;MetaTagAll&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;MetaTagAll&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;formError&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;can't be empty&lt;span class=&quot;MetaTagAll&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; error_message_on &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;post&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;title&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt; =&amp;gt;
&lt;span class=&quot;MetaTagAll&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;MetaTagAll&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;formError&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;can't be empty&lt;span class=&quot;MetaTagAll&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;&amp;lt;%=&lt;/span&gt; error_message_on &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;post&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;title&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;Title simply &lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt; (or it won't work).&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;EmbeddedSourceBright&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;inputError&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;EmbeddedSourceBright&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt; =&amp;gt;
&lt;span class=&quot;MetaTagAll&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;MetaTagAll&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;inputError&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Title simply can't be empty (or it won't work).&lt;span class=&quot;MetaTagAll&quot;&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;MetaTagAll&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;MetaTagAll&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;ปล. นึกไม่ออกว่าข้อความไหน อยู่ตรงไหน ย้อนกลับไปด&lt;a href=&quot;http://weblog.punneng.net/2007/4/2/ruby-on-rails-customized-validation&quot;&gt;ของเก่า&lt;/a&gt;ได้ครับ&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.net/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.net,2008-04-15:775</id>
    <published>2008-04-15T16:26:00Z</published>
    <updated>2008-04-15T17:41:24Z</updated>
    <category term="General"/>
    <link href="http://weblog.punneng.net/2008/4/15/debugging-actionscript-with-firebug" rel="alternate" type="text/html"/>
    <title>Debugging ActionScript with Firebug</title>
<content type="html">
            &lt;p&gt;ผมทำ flash ก้อนนึง ให้&lt;a href=&quot;http://gotoknow.org/profile/tonkla&quot;&gt;เพื่อนผม&lt;/a&gt;อยู่ ตอนทำก็ปกติดี แต่ตอนเอาขึ้นเว็บแล้วต้องทดสอบนี่สิ  ไอ้หยาาา!! มัน trace ไม่ได้  &lt;/p&gt;

&lt;p&gt;เมื่อ trace(); ไม่แสดงผลบน browser จะ debug ยังไง ??  &lt;/p&gt;

&lt;p&gt;เมื่อก่อนใช้ &lt;a href=&quot;http://osflash.org/xray&quot;&gt;xRay&lt;/a&gt; ก็ ok นะ trace ได้เยอะดี    &lt;/p&gt;

&lt;p&gt;แต่ตอนนี้ ขี้เกียจติดตั้ง เล่นมันง่ายๆ กับ Firebug นี่แหละ  ไม่เคยใช้ ?? เข้านี่เลย -&gt; &lt;a href=&quot;http://www.getfirebug.com/&quot;&gt;Firebug&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;ใน Firebug เราสามารถ print ค่าอะไรบางอย่างได้ด้วย colsole.debug(what&lt;em&gt;you&lt;/em&gt;want); ใน JavaScript 
ยังมี console.log, console.info, console.warn, and console.error อีกด้วย
ตอนที่ให้ flash แสดงผล ก็บน browser เช่นกัน !! อะฮ้า จัดการต่อ flash(AS3) ไปยัง JavaScript เสียเลย ได้หน้าตาแบบนี้  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Storage&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;firebug&lt;/span&gt;(&lt;span class=&quot;Variable&quot;&gt;msg:String&lt;/span&gt;)&lt;span class=&quot;Keyword&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;SupportFunction&quot;&gt;void&lt;/span&gt;{
  ExternalInterface.&lt;span class=&quot;SupportFunction&quot;&gt;call&lt;/span&gt;(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;console.debug&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, msg);
}
firebug(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;what_you_want&lt;span class=&quot;String&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;สำหรับ AS2 ก็เหมือนๆ กัน  &lt;/p&gt;

&lt;table class=&quot;jazzy&quot;&gt;&lt;tr&gt;&lt;td class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line-numbers&quot;&gt;  1&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  2&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  3&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;&lt;span class=&quot;Storage&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;firebug&lt;/span&gt;(&lt;span class=&quot;Variable&quot;&gt;msg:String&lt;/span&gt;)&lt;span class=&quot;Keyword&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;SupportFunction&quot;&gt;void&lt;/span&gt;{
  &lt;span class=&quot;SupportFunction&quot;&gt;getURL&lt;/span&gt;(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;javascript:console.debug(msg)&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
}
firebug(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;what_you_want&lt;span class=&quot;String&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;เฮ้ละ IE(และศัตรูอย่าง Safari/Opera) ไม่มี Firebug!!  &lt;/p&gt;

&lt;p&gt;โหลด &lt;a href=&quot;http://www.getfirebug.com/lite.html&quot;&gt;Firebug lite&lt;/a&gt; ไปใช้ได้  &lt;/p&gt;

&lt;p&gt;ปล. ที่ไม่ค่อยได้เขียน blog เพราะทำ flash ให้เพื่อนผมอยู่(เป็นแพะไปซะ วะฮะฮ่า)&lt;br /&gt;
ปอ. ผมรัก Firebug&lt;/p&gt;
          </content>  </entry>
</feed>
