Installing Merb

Posted by PunNeng, Sun Jul 13 15:50:00 UTC 2008

เกริ่นก่อนนิดนึง อะไรคือ Merb??

Merb ก็เป็น MVC Framework เช่นเดียวกับ Ruby on Rails เพียงแต่มันสามารถกำหนดฝั่ง View และ Model เองได้ แต่เห็นจะเน้นไปที่ฝั่ง Model มากกว่า สามสิ่งที่นิยมใช้กับฝั่ง Model ก็คือ ActiveRecore, DataMapper และ Sequel

นั่นหมายความว่า เราสามารถจะเอาไอ้นั่น ไอ้นี่ มาปะติดปะต่อเองได้ เรื่องของเรื่องคือ Ruby on Rails มันช้า magic มันเยอะ บางคนไม่ชอบ magic เพราะมันเกินความจำเป็น(แต่ผมชอบ) ถ้าตัดออกได้ หรือเปลี่ยนได้ ก็น่าจะดีกว่า กอปรกับความเทอะทะของ Rails เอง ทีมที่พัฒนา Merb ก็เลยจัดการเขียนใหม่ซะ

จุดเด่นโดยรวมของ Merb ก็คือ เรื่องความเร็ว(ที่ดีกว่า Rails) และการเลือกใช้ฝั่ง View และ Model เองได้(ผมเลือก DataMapper)

มาเริ่มติดตั้งกัน
ผมจะติ๊งต่างว่าทุกท่านที่เข้ามาอ่านใน blog ผม คงจะเคยติดตั้ง Rails กันมาบ้างแล้ว และสิ่งหนึ่งที่จำเป็นต้องมีคือ RubyGems ดังนั้น ผมจึงข้ามเรื่องการติดตั้ง RubyGems ไป

ก่อนที่จะติดตั้งได้สมบูรณ์ ก็ลองผิดลองถูกมานาน จนได้สูตรสำเร็จว่า update มันใหม่ให้หมด ก็ติดตั้งได้เอง ก็เริ่มด้วยการ upgrade RubyGems ละกัน

$ sudo gem update --system

และ Ruby(1.8.6 เป็นอย่างต่ำ)
วิธีการ upgrate ขึ้นอยู่กับแต่ละท่านครับ บางคน apt-get บางคน MacPorts หรือบางคนก็ compile เองแม่งเลย

สิ่งต่อไปที่ต้องมีคือ Git
บน Ubuntu

$ sudo apt-get install git

บน OSX Leopard

บน OSX Tiger

ก่อนจัดการกับ Merb ก็ติดตั้งพวก gem dependency ก่อน

$ sudo gem install rack mongrel json erubis mime-types rspec hpricot mocha rubigen haml markaby mailfactory ruby2ruby

จากนั้น clone Merb มาด้วย

$ 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

แล้วก็ติดตั้ง

$ cd merb-core ; rake install ; cd ..    
$ cd merb-more ; rake install ; cd ..
$ cd merb-plugins; rake install ; cd ..

ฝั่ง Model ผมเลือก DataMapper เพราะหน้าตาคล้ายกับ ActiveRecord แต่เบากว่า

clone driver ก่อน

$ git clone git://github.com/sam/extlib.git  
$ git clone git://github.com/sam/do.git

แล้วก็ติดตั้ง

$ cd extlib ; rake install ; cd ..
$ cd do 
$ cd data_objects ; rake install ; cd ..
$ cd do_mysql  # || do_postgres || do_sqlite3
$ rake install

ผมเลือก mysql

ขั้นตอนนี้จะมีปัญหานิดหน่อย ขณะที่ติดตั้ง do_mysql
บน Ubuntu ถ้าหากใช้ mysql ที่ติดตั้งเอง แล้ว home directory มันไม่อยู่ที่ default path มันจะมองหา mysql home ไม่เจอ และอีกปัญหานึงคือ มันจะหา mysql.h ไม่เจอ วิธีซ่อมคือ

$ sudo apt-get install mysql

และ libmysqlclient15 สำหรับ myslq.h มันจะไปอยู่ใน /usr/include/mysql

$ sudo apt-get install libmysqlclient15-dev

สำหรับ OSX ก็เหมือนกัน มันจะหา home directory ไม่เจอ ผมแนะนำให้โหลดจากเว็บมันเลย ที่หน้า download อันนี้มี mysql.h มาให้ด้วย
มันยังไม่ใช่แค่นี้ ต้องไปใช้กำลังกันหน่อย
ตอนติดตั้ง mysql ไอ้ home directory มันจะไปอยู่ที่ /usr/local/mysql
ก็ต้องไประบุเพิ่มนิดนึงใน Rakefile ของ do_mysql จะมี

  1
  2
  3
task :install => [ :package ] do
  sh %{#{SUDO} gem install --local pkg/#{spec.name}-#{spec.version} --no-update-sources}, :verbose => false
end

ให้เพิ่ม -- --with-mysql-dir=/usr/local/mysql ไปด้วย เป็น

  1
  2
  3
task :install => [ :package ] do
  sh %{#{SUDO} gem install --local pkg/#{spec.name}-#{spec.version} --no-update-sources -- --with-mysql-dir=/usr/local/mysql}, :verbose => false
end

ยังไม่จบครับ clone ตัว DataMapper กันต่อ

git clone git://github.com/sam/dm-core.git
git clone git://github.com/sam/dm-more.git

แล้วก็ติดตั้ง

$ cd dm-core ; rake install ; cd ..
$ cd dm-more ; rake install

เท่านี้น่าจะเสร็จสิ้น ลองแบบง่ายๆ

$ merb-gen app your_project_name
$ cd your_project_name
$ merb

ก็น่าจะทำงานได้ปกติ ถ้าไม่ปกติ ก็ลง comment หรือ error ไว้ได้ครับ จะช่วย debug

ปล. ยังมีตอนต่อไปอีกหลายตอนครับ
ปอ. สำหรับบน Windows ไปเอาตัวรอดกันเองนะครับ =='

ข้อมูลจาก merb.4ninjas

2 comments | Filed Under: Merb | Tags: datamapper howto installing merb

Modifying fieldWithErrors

Posted by PunNeng, Sat Jul 05 20:33:00 UTC 2008

fieldWithErrors เนี่ย บางทีมันก็มีประโยชน์ดีนะ แต่บางทีก็อยากจะเอาออก หรืออยากจะแก้ไข

เอาแบบนี้ดีกว่า

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|          
  if html_tag =~ /<label.*>.*<\/label>/
    "<div class=\"labelWithErrors\">#{html_tag}</div>" 
  elsif html_tag =~ /terms_and_conditions/   
    "<div class=\"tickWithErrors\">#{html_tag}</div>"
  elsif html_tag =~ /radio/
    "<div class=\"radioWithErrors\">#{html_tag}</div>"     
  else
    "<div class=\"fieldWithErrors\">#{html_tag}</div>"      
  end                            
end

ใส่ไปใน environment.rb
ใครมีความคิดอะไรก็ใส่ไปให้หมด สำหรับผมการ filter ง่ายๆ ก็ใช้ RegExp ครับ

ไม่มีกะจิตกะใจจะเขียนเท่าไหร่ กำลังทะเลาะกับ Merb อยู่ ทำไมมันติดตั้งยากเยี่ยงนี้ !!

0 comments | Filed Under: Ruby on Rails | Tags: activerecord fieldwitherrors howto ruby on rails

Ruby on Rails :: Customize Form helper

Posted by PunNeng, Sun Jun 29 03:00:00 UTC 2008

เพิ่งทำของเล่นเสร็จไปตัวนึง เลยไม่ได้เขียน blog

ไม่ต้องพล่ามมาก เอาเลยดีกว่า

ใน Rails มี Form helper อยู่ เราทำอะไรกับมันได้บ้าง?? ลองดูแบบนี้ก่อน

  1
  2
  3
  4
  5
  6
<% form_for :person, @person, :url => { :action => "update" } do |f| %>
  First name: <%= f.text_field :first_name %>
  Last name : <%= f.text_field :last_name %>
  Biography : <%= text_area :person, :biography %>
  Admin?    : <%= check_box_tag "person[admin]", @person.company.admin? %>
<% end %>

ปกติ ผมจะต้องใส่ label ให้มันด้วย
ผมไม่ค่อยชอบเลย ผมอยากได้

f.text_field :first_name

แล้วมันใส่ label ไปให้ผมเลย
มันทำได้โดยสร้าง module เพิ่ม ไปใว้ใน config/initializers/ (มันมาตอน rails 2.0 ออกมั้ง ทุก file ในนี้ จะถูกโหลดโดยอัติโนมัติ)

  1
  2
  3
  4
  5
  6
  7
module MyFormHelper
  class MyFormBuilder < ActionView::Helpers::FormBuilder
    def text_field(method, options = {})
      @template.content_tag('p', label(method) + <br /> + super)
    end
  end
end

ก็ extends ตามเรื่องไป(ต้องใช้พลังแงะนิดหน่อย)

ใน form ด้านบน ก็เพิ่ม :builder => MyFormHelper::MyFormBuilder
หน้าตาจะเป็นแบบนี้

  1
  2
  3
  4
  5
  6
<% form_for :person, @person, :url => { :action => "update" }, :builder => MyFormHelper::MyFormBuilder do |f| %>
  <%= f.text_field :first_name %>
  <%= f.text_field :last_name %>
  <%= text_area :person, :biography %>
  <%= check_box_tag "person[admin]", @person.company.admin? %>
<% end %>

แล้วผมก็จะได้ผลของการ render text_field เป็นแบบนี้

  1
  2
<p><label for="person_first_name">First name</label><br />
<input type="text" id="person_first_name" name="person[first_name]"</p>

อะไรประมาณนี้

0 comments | Filed Under: Ruby on Rails | Tags: form helper helper howto ruby on rails

Inverse Captcha

Posted by PunNeng, Fri Jun 06 16:59:00 UTC 2008

ดีใจมากครับ ในที่สุด blog ผมก็หมดปัญหาเรื่อง spam ไปเสียที เย้..

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

หลังจากการ search หา plugin ดูใน google ตัวแรกที่เจอคือ Inverse Captcha ครับ แค่ชื่อก็น่างงแล้ว

แต่หลังจากใช้ไป 1 อาทิตย์ ไม่มี spam หลุดมาสักตัว(ใน blog ของ Sven Fuchs เอง เขาก็ทดลองเดือนนึง) ไม่ต้องมี captcha แปะให้น่ารำคาญ ไม่ต้องเพ่งตัวอักษรที่อ่านยากแสนยาก

หลังจากที่ลองเล่นดูแล้ว ก็ได้ความว่า

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

comment[author]
comment[author_email]
comment[author_url]
comment[body]

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

comment[author]
comment[author_xxxxxx]
comment[author_url]
comment[body]
comment[author_email] #display:none;

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

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

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

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

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

ว่าแต่มัน inverse ยังไงเนี่ย =='

ปล. เดี๋ยวจะ implement ให้ดูอีกทีครับ จะได้เข้าใจในเชิงลึกอีกที

2 comments | Filed Under: General | Tags: inverse captcha spam

RailsDB

Posted by PunNeng, Wed May 28 02:46:00 UTC 2008

ทุกชิ้นงาน(ของออฟฟิศ)ที่ผมทำบน rails อยู่ทุกวันนี้ host ด้วย vps ครับ แล้วตอนติดตั้ง ก็ขี้เกียจติดตั้งชุดแปล php ด้วย ผมเลยอยากได้อะไรเหมือน phpmyadmin ครับ
ทางเลือกแรก ต้องใช้ edge rails
มีตัวช่วยใหม่ ชื่อว่า dbconsole แต่ก็ยังเป็น command line แค่มัน remote ให้ แค่นั้นเอง
ทางเลือกที่สองก็คือ RailsDB
ทางเลือกที่สาม เอ่อ.. ช่วย comment บอกที

ย้อนกลับมาที่ RailsDB ครับ น่าจะใช้แทน phpmyadmin ได้มากที่สุด คืนนี้ ผมก็เลยลองซะ ผลที่ได้คือ error!!(เป็นปกติ)

มันพังเพราะ default config มันผิด ตอนต่อ db หน้าตาประมาณนี้

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
def switch_db( database )     
    case database.driver.name
      when 'sqlite3'
        ActiveRecord::Base.establish_connection(
          :adapter  => 'sqlite3',
          :database => database.path
        )
      when 'mysql'
        ActiveRecord::Base.establish_connection(
          :adapter  => 'mysql',
          :database => database.name,
          :host     => database.host,
          :username => database.username,
          :password => database.password
        )
      when 'postgresql'
        ActiveRecord::Base.establish_connection(
          :adapter  => 'postgresql',
          :database => database.name,
          :host     => database.host,
          :username => database.username,
          :password => database.password
        )
    end
  end

code ชุดนี้ อยู่ที่ app/models/switch.rb ครับ
สังเกตได้ว่า มันไม่มี port หรือ socket ให้กรอกครับ ค่า default ของ mysql ใน activerecord เองก็กำหนดไว้ว่า port เป็น 3306 และ socket เป็น /tmp/mysql.sock

วิธีซ่อมก็ง่ายๆ ครับ ใส่่ port หรือ socket ที่ถูกต้องเข้าไป

ประชาสัมพันธ์หน่อยครับ
มีงาน train (J)Ruby on Rails ของ narisa นะครับ ใครสนใจก็ตาม link ข้างล่างเลย
วันจัด train เรื่อง (J)Ruby On Rails ครับ - Narisa.com

2 comments | Filed Under: Ruby on Rails | Tags: activerecord database phpmyadmin railsdb ruby on rails

codegent: we're hiring