<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>PunNeng on Rails 2.0 LIVE - Home</title>
  <id>tag:weblog.punneng.com,2008:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://weblog.punneng.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://weblog.punneng.com/" rel="alternate" type="text/html"/>
  <updated>2008-08-02T13:18:54Z</updated>
  <entry xml:base="http://weblog.punneng.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,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.com/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.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,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.com/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.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,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.com/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.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,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.com/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.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,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.com/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.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,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.com/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.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,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.com/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.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,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.com/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.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,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.com/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.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,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.com/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>
  <entry xml:base="http://weblog.punneng.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,2008-03-09:596</id>
    <published>2008-03-09T14:52:00Z</published>
    <updated>2008-03-09T14:54:30Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.com/2008/3/9/bdd-guide-1-when-do-i-mock" rel="alternate" type="text/html"/>
    <title>BDD guide #1 When do I mock?</title>
<content type="html">
            &lt;p&gt;ผมเคยสับสนมานานว่าเมื่อไหร่ควรจะ mock และคนที่เคลียร์ปัญหาคาใจผมก็คือ&lt;a href=&quot;http://kingselassie.wordpress.com/&quot;&gt;เจ้านาย&lt;/a&gt;ผมเอง&lt;br /&gt;
เขาบอกโดยสรุปว่า&lt;/p&gt;

&lt;blockquote&gt;mock ในส่วนที่เราไม่พิจารณา&lt;/blockquote&gt;  

&lt;p&gt;เช่นใน controller เราจะพิจารณาที่ logic ของ controller เท่านั้น ในส่วนของ model ที่เราเรียกใช้งานก็ไม่ต้องสนว่าจริงๆ แล้วมันทำงานยังไง เราเลย mock ที่ model ไปเลย ส่วนจะ lock การคืนค่าหรือตัวแปรต่างๆ ก็ stub เอา ส่วน logic ต่างๆ ก็&lt;br /&gt;
กระโดนมาส่วน model บ้าง ในส่วนของ model ที่เรา mock ใน controller ไปแล้ว เราควรจะมา test อีกที ทีนี้เราพิจารณา logic ใน model ซึ่งโดยมากแล้วก็ไม่รู้จะ mock อะไร เพราะมันล้วนซึ่งต้องทำงานตาม code ที่เขียนไว้จริงๆ(ดูคล้ายๆ กับ unit test)  &lt;/p&gt;

&lt;p&gt;มาดูตัวอย่างกัน&lt;br /&gt;
&lt;a href=&quot;http://weblog.punneng.com/2007/11/25/learning-rspec-form-rspec-scaffold&quot;&gt;ตัวอย่าง 1&lt;/a&gt;&lt;br /&gt;
อันนี้เป็นตัวอย่างจาก scaffold&lt;br /&gt;
สิ่งที่ mock ล้วนซึ่งเป็น model ทั้งนั้น เริ่มจาก before ด้วยการ mock ไปก่อนแล้วตามด้วย stub&lt;br /&gt;
ที่ต้อง stub เพราะต้องจำลองผล เพราะเรา mock model มาอีกทีนึง มันจึงไม่แตะ code ของ model จริงๆ&lt;br /&gt;
ยังมีส่วนของการ render/redirect ใน controller อีก แต่อันนี้ เราจำเป็นต้องวัดผล(พิจารณา)มันจริงๆ เลยไม่จำเป็นต้อง mock ในส่วนของ render/redirect  &lt;/p&gt;

&lt;p&gt;ตัวอย่าง 2 จาก&lt;a href=&quot;http://www.lukeredpath.co.uk/2006/8/29/developing-a-rails-model-using-bdd-and-rspec-part-1&quot;&gt;Luke Redpath&lt;/a&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;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;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;describe &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;A user (in general)&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
  setup &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;user&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;User&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;new&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

  it &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;should be invalid without a username&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;user&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;email&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;joe@bloggs.com&lt;span class=&quot;String&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;user&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;should_not_be_valid&lt;/span&gt;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;user&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;errors&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;on&lt;/span&gt;(&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;username&lt;/span&gt;).&lt;span class=&quot;Entity&quot;&gt;should_equal&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;is required&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; 
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;user&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;username&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;someusername&lt;span class=&quot;String&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;user&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;should_be_valid&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

  it &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;should be invalid without an email&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;user&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;username&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;joebloggs&lt;span class=&quot;String&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;user&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;should_not_be_valid&lt;/span&gt;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;user&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;errors&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;on&lt;/span&gt;(&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;email&lt;/span&gt;).&lt;span class=&quot;Entity&quot;&gt;should_equal&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;is required&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; 
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;user&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;email&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;joe@bloggs.com&lt;span class=&quot;String&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;user&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;should_be_valid&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;ตัวอย่างนี้ไม่มี mock สักตัว เพราะต้องการ test logic ที่มันควรจะเป็นจริงๆ  &lt;/p&gt;

&lt;p&gt;แต่ถ้า model มีการทำงานร่วมกับ model ตัวอื่น อันนี้ก็น่าจะ mock เป็นต้น  &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,2008-02-24:562</id>
    <published>2008-02-24T08:55:00Z</published>
    <updated>2008-02-24T08:56:41Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.com/2008/2/24/ruby-on-rails-default-mime-types" rel="alternate" type="text/html"/>
    <title>Ruby on Rails :: Default mime types</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://gotoknow.org/profile/tonkla&quot;&gt;ต้นกล้า&lt;/a&gt;มาถามว่า เวลาใช้ &lt;a href=&quot;http://api.rubyonrails.org/classes/ActionController/MimeResponds/InstanceMethods.html&quot;&gt;respond_to&lt;/a&gt; แล้วเกิดรับ format ของ mime type ที่ไม่ได้เซ็ตไว้ มันก็จะทำงานไม่ถูกต้อง ผลที่ได้คือ จะได้ error &lt;a href=&quot;http://www.checkupdown.com/status/E406.html&quot;&gt;406 Not Acceptable&lt;/a&gt;&lt;br /&gt;
วิธีซ่อมง่ายๆ จากการแงะ plugin ที่ชื่อว่า &lt;a href=&quot;http://agilewebdevelopment.com/plugins/exception_notifier&quot;&gt;exception_notifier&lt;/a&gt; คือใช้ format.all &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;respond_to &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;format&lt;/span&gt;|
  format.&lt;span class=&quot;Entity&quot;&gt;html&lt;/span&gt; 
  format.&lt;span class=&quot;Entity&quot;&gt;all&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;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;  

&lt;p&gt;ถ้าไม่ใส่ block เพิ่มไป มันจะไปเรียก index.all.erb ในกรณีที่ใช้ restful&lt;br /&gt;
แต่ถ้าไม่ใช้ ก็จะเป็น html ไป  &lt;/p&gt;

&lt;p&gt;ก็มาสงสัยอีว่า default mime type ที่เซ็ตไว้มีอะไรบ้าง ก็ไปแงะมา เจอ&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;/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; Build list of Mime types for HTTP responses&lt;/span&gt;
&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; http://www.iana.org/assignments/media-types/&lt;/span&gt;

&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&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;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;all&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;text/plain&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;text&lt;/span&gt;, [], &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%w(&lt;/span&gt;txt&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;text/html&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;html&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%w(&lt;/span&gt; application/xhtml+xml &lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%w(&lt;/span&gt; xhtml &lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&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;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;js&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%w(&lt;/span&gt; application/javascript application/x-javascript &lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;text/css&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;css&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;text/calendar&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;ics&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;text/csv&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;csv&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;application/xml&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;xml&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%w(&lt;/span&gt; text/xml application/x-xml &lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;application/rss+xml&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;rss&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;application/atom+xml&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;atom&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;application/x-yaml&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;yaml&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%w(&lt;/span&gt; text/yaml &lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;multipart/form-data&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;multipart_form&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;application/x-www-form-urlencoded&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;url_encoded_form&lt;/span&gt;

&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; http://www.ietf.org/rfc/rfc4627.txt&lt;/span&gt;
&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;application/json&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;json&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;%w(&lt;/span&gt; text/x-json &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;ถ้าจะเพิ่ม ก็ไปประกาศได้ที่ environment.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;&lt;span class=&quot;Support&quot;&gt;Mime&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Type&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;image/jpg&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;jpg&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,2008-02-19:559</id>
    <published>2008-02-19T19:04:00Z</published>
    <updated>2008-02-19T19:16:41Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.com/2008/2/19/mailer-testing" rel="alternate" type="text/html"/>
    <title>Mailer Testing</title>
<content type="html">
            &lt;p&gt;Mailer Testing&lt;/p&gt;

&lt;p&gt;ไปเจอมาจาก&lt;a href=&quot;http://kpumuk.info/ruby-on-rails/testing-mailers-with-rspec/&quot;&gt;ที่นี่&lt;/a&gt; ตัด code ที่ผมคิดว่าไม่จำเป็นออก&lt;br /&gt;
ในส่วนของ model หน้าตาก็จะได้ประมาณนี้&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;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;sunburst&quot;&gt;describe &lt;span class=&quot;Variable&quot;&gt;EmailSender&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
  setup &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;expected&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;TMail&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;Mail&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;new&lt;/span&gt;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;expected&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;set_content_type&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;text&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;plain&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, { &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;charset&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;utf-8&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; }
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;expected&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;mime_version&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;1.0&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;

  it &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;should create an email&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;expected&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;subject&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;Rspec&lt;span class=&quot;String&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;expected&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;body&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;Rspec is so cool.&lt;span class=&quot;String&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;expected&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;from&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;myemail@myemail.com&lt;span class=&quot;String&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;expected&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;to&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;youremail@youremail.com&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;Support&quot;&gt;EmailSender&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;create_your_email&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;encoded&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;expected&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;encoded&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;ทดสอบแค่ create พอ ไม่จำเป็นต้องส่ง ถ้าจะส่งก็แค่เรียก EmailSender.deliver(EmailSender.create_your_email)  &lt;/p&gt;

&lt;p&gt;แต่ปกติแล้วเราาจะใช้ EmailSender.deliver&lt;em&gt;your&lt;/em&gt;email  &lt;/p&gt;

&lt;p&gt;ในฝั่ง 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;describe &lt;span class=&quot;Variable&quot;&gt;YourController&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
  it &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;should send email&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;Support&quot;&gt;EmailSender&lt;/span&gt;.&lt;span class=&quot;Entity&quot;&gt;should_receive&lt;/span&gt;(&lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;deliver_your_email&lt;/span&gt;)
    post &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;your_action&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;a href=&quot;http://tmail.rubyforge.org/&quot;&gt;TMail&lt;/a&gt; นี่แหละครับ ตัว ActionMailer ก็ใช้ TMail เหมือนกัน&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.punneng.com/">
    <author>
      <name>PunNeng</name>
    </author>
    <id>tag:weblog.punneng.com,2008-02-10:519</id>
    <published>2008-02-10T09:12:00Z</published>
    <updated>2008-02-13T19:08:32Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://weblog.punneng.com/2008/2/10/differences-between-stub-and-should_receive" rel="alternate" type="text/html"/>
    <title>differences between stub! and should_receive</title>
<content type="html">
            &lt;p&gt;ใน rspec มีศัพท์แสง(method)หลายๆ คำที่ชวนทำผมงง เช่น mock หรือ stub พอเขียนไปเรื่อยๆ ก็มี should_receive โผล่มาอีก ตอน return ก็มี and_return เข้ามาอีก ตอนแรกกับ rspec นี่ ผมแทบร้องไห้ คือพยายามทำความเข้าใจกับมัน แต่ก็ไม่เข้าใจว่า ไอ้ stub นี่ ทำไปทำไม ?? หรือ and_return นี่ มันคือการตรวจสอบค่า return หรือเปล่า ??  &lt;/p&gt;

&lt;p&gt;หลังจากที่ลองมันไปสักพัก ปรากฏว่ามีอยู่สองอย่างเท่านั้นที่ผมทำยังไงก็ไม่เข้าใจสักที คือ stub! กับ should_receive แต่ตัวที่ทำให้ผมงงจริงๆ กับสองตัวนี้ คงจะเป็น and_return มากกว่า จนแล้วจนรอดก็ไปเจอพระเอกขี่ม้าขาวจนได้ เป็น&lt;a href=&quot;http://rspec.info/documentation/mocks/stubs.html&quot; title=&quot;RSpec-1.1.3: Method Stubs&quot;&gt;ตัวอย่างในเว็บของ rspec เอง&lt;/a&gt;  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;A.stub!(:msg).and_return(:default_value)
A.should_receive(:msg).with(:arg).and_return(:special_value)
A.msg
=&gt; :default_value
A.msg(:any_other_arg)
=&gt; :default_value
A.msg(:arg)
=&gt; :special_value
A.msg(:any_other_other_arg)
=&gt; :default_value
A.msg
=&gt; :default_value
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;ความแตกต่าง&lt;/strong&gt;&lt;br /&gt;
stub! คือ การจำลองพฤติกรรมของ method ว่าควรจะรับอะไรแล้วส่งอะไร (คล้ายๆ กับ mock แต่ไม่ใช่ mock)&lt;br /&gt;
should_receive คือ การตรวจสอบว่า method หรือ variable ที่เราคาดหวังไว้ เป็นไปตามที่เราคิดไว้หรือเปล่า(แต่จะไม่ตรวจสอบการคืนค่า)&lt;br /&gt;
and_return คือ การกำหนดการคืนค่า  &lt;/p&gt;

&lt;pre class=&quot;terminal&quot;&gt;A.stub!(:msg).and_return(:default_value)&lt;/pre&gt;
จำลองไว้ก่อนว่าถ้ารับ :msg มา จะคืนค่าเป็น :default_value  
&lt;pre class=&quot;terminal&quot;&gt;A.should_receive(:msg).with(:arg).and_return(:special_value)&lt;/pre&gt;
ตรวจสอบว่า มันควรจะได้รับ :msg พร้อมกับ :arg เป็น argument และจะคืนค่าเป็น :special_value
&lt;pre class=&quot;ter