Displaying articles with tag activerecord

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

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

Better error messages for validation

Posted by PunNeng, Sat Apr 26 02:38:00 UTC 2008

แว่บๆ ไปอ่าน feed เจอของ Softies on Rails
error_messages_for เปลี่ยนไป(ตอนไหนไม่รู้)
ที่เคยเขียนไปของเก่า จำได้ว่ามันแก้ header_messages ไม่ได้ เลยต้องแก้เอง เพราะหน้าตาใน helper ของเก่าเป็นแบบนี้

  1
header_message = "#{pluralize(count, 'error')} prohibited this #{(options[:object_name] || params.first).to_s.gsub('_', ' ')} from being saved"

แว่บไปดูใน API ไปเจอว่าเปลี่ยนไปจริงๆ ได้ของแถมมาอีก คือ error_messages_on ซึ่งผมไม่เคยใช้มาก่อน(บ้านนอก)

list ข้างล่างคือค่า params ที่เราจะใส่ไปได้ใน error_messages_for

  • header_tag ค่า default เป็น h2
  • id ค่า default เป็น errorExplanation
  • class ค่า default เป็น errorExplanation
  • object ไว้เซ็ตค่ากรณีที่ไม่มี object ที่ต้องใส่ตาม convention เช่น

error_messages_for 'user'

ถ้าจะให้ขึ้น ฝั่ง view จะต้องมองเห็น @user แล้ว error ถึงจะออก
แต่แบบใหม่นี่ สามารถอ้างได้จาก object อื่นได้เลย เช่น

error_messages_for 'user', @question.user

  • object_name ตรงตัว ถ้าไม่ใส่ จะไปใช้ object แทน ในตัวอย่างคือ User
  • header_message ตรงตัว ค่า default เป็น X errors prohibited this object from being saved ซึ่ง X ก็คือ object_name นั่นแหละ
  • message คือข้อความที่อยู่ใต้ header_message และมาก่อน error list ค่า default เป็น There were problems with the following fields:

ถัดมาก็ error_message_on
ไม่มีอะไรง่ายกว่าการดูตัวอย่าง

  1
  2
  3
  4
  5
  6
  7
  8
<%= error_message_on "post", "title" %> =>
<div class="formError">can't be empty</div>

<%= error_message_on @post, "title" %> =>
<div class="formError">can't be empty</div>

<%= error_message_on "post", "title", "Title simply ", " (or it won't work).", "inputError" %> =>
<div class="inputError">Title simply can't be empty (or it won't work).</div>

ปล. นึกไม่ออกว่าข้อความไหน อยู่ตรงไหน ย้อนกลับไปดของเก่าได้ครับ

0 comments | Filed Under: Ruby on Rails | Tags: activerecord

Ruby on Rails :: ActiveRecord

Posted by PunNeng, Sat May 20 23:12:00 UTC 2006

ต่อจากคราวที่แล้ว มันยังไม่จบนะครับ มันยังมีสิ่งที่น่าสนใจอยู่อีก

ในทุกๆ วันนี้ database เห็นจะแยกออกจาก web application ไม่ได้ซะแล้ว ไม่ว่าจะทำอะไร จะทำเว็บขายของ หรือแม้กระทั้ง text base อย่าง blog หรือเว็บข่าวสาร ก็ยังคงต้องใช้ database ในการเก็บข้อมูล หนีไม่พ้น

ตอนนี้เราใช้ database แบบ relation ซึ่งแบบ relation เนี่ย มันเป็นสิ่งที่ดีสำหรับการออกแบบ สำหรับการที่จะเข้ามาดูมัน ดูแล้วมันเข้าใจง่ายๆ แต่มันทำให้ยากที่จะเชื่อมต่อระหว่าง database แบบ relation กับภาษาเชิง OO ซึ่ง Object นั้น เป็นทุกๆ อย่าง เป็นข้อมูล เป็น operations และ database ก็เป็นชุดของข้อมูล มันง่ายสำหรับการมองอย่าง relation แต่มันก็เป็นสิ่งที่ยากถ้ามองอย่าง OO

ถ้าเราเขียนโปรแกรมต่อ database โดยใช้ภาษาเชิง procedural อย่าง C เป็นต้น เราก็ต้องเขียน sql command ลงไปใน code ของเรา หรือจะใช้ preprocessor ทำการ convert sql ไว้ก่อน แล้วค่อยเรียกเข้ามาใช้งาน ในตัวงานของเราก็จะผสมปนเประหว่าง logic ของตัว database กับ logic ของงานของเรา ใครที่เคยเขียนมา ก็คงจะเข้าใจ ว่ามันจะอิรุงตุงนังกันขนาดไหน เวลาจะเอางานเก่ามาแก้ทีนึง หรือเอามาปรับปรุง ต่อยอด มันจะงงๆ แน่นอน (ฉันทำอะไรลงไปเนี่ย) ดูยุ่งเหยิง การเขียนแบบนี้ เขาก็ใช้กันทั่วๆ ไป แต่มันจะเหมาะสำหรับงานเล็กๆ มากกว่า แล้วเราต้องมาเรียนรู้ sql กันอีก กว่าจะทำงานพวกนี้ได้ ถ้ามีการต้องต่อกับ database อีก เหมือนๆ ของเดิม แต่เป็นที่อื่น เราก็แค่ copy code ไปวางไว้ที่ๆ นั้น ถ้างานเราใหญ่มากๆ copy ไปๆ มา จะมึนซะอีก มันดูไม่ค่อยสวยเลยแฮะ

แต่ในภาษาเชิง OO ที่เรารู้จัก การทำ encapsulation มันจะแก้ปัญหาพวกนี้ออกไป มันจะห่อของพวกนี้ ไว้ในกลุ่มๆ นึง ที่เราเรียกกันว่า class ซึ่งเราจะสร้างเจ้า class นี้ เพียงก้อนเดียว ก็สามารถทำการเปลี่ยนแปลงเจ้าความวุ่นวายข้างบนได้แล้ว

แล้วก็มีพวกมนุษย์หัวใส ได้ต่อเติมความคิดแบบนี้สำหรับการเขียนโปรแกรมกับ database เขาห่อพวก code ที่จะทำการติดต่อกับ database ไว้ภายใต้ class อันนึง เวลาเราจะใช้งาน ก็มาเรียกผ่าน class อันนี้ การที่จะห่อ code พวกนี้ ไว้ภายใต้ class จะต้องห่อเจ้าพวก schema ลงไปด้วย แล้วแยก business logic ออกจากระดับ low-level(sql command ต่างๆ) มันดูยากถ้าจะเอามาเขียนโปรแกรมจริงๆ เพราะ database จริงๆ มันจะติดต่อกับอะไรบ้างก็ไม่รู้ แต่ถ้าเรามามองการติดต่อกันนัวเนียๆ ในรูป Object ล่ะ มันดูยากแน่ๆ แต่แล้วอุตสาหกรรมคอมพิวเตอร์ ก็สร้างมันออกมาได้ มันคือ ORM หรือ Object/Relation Mapping ซึ่ง Rails ก็ใช้ ORM นี้เหมือนกัน

Object/Relation Mapping

ORM มันจะทำการจับคู่ ผูก(map) เชื่อมต่อกับ table ใน database ให้เป็น class ถ้าเกิด table ของเราชื่อ Orders หลังจากการ map ไปแล้ว จะได้ class ที่ชื่อว่า Order แต่ละ row ใน table ก็จะเหมือน object ของ class อันนี้ ส่วน column ก็จะกลายเป็น attribute ของ object นั้นๆ ไป แล้วใน class นี้ ก็จะมี method สำหรับ query ค่าออกมา

จากที่กล่าวมา class ของ Rails จะทำการห่อหุ้ม table ของ database เอาไว้ แล้วแบ่งออกเป็นระดับ ส่วนที่เป็น class จะทำหน้าที่เหมือน table มาดูตัวอย่าง เราต้องการหา order จาก id

order = Order.find(1) 
puts "Order #{order.customer_id}, amount=#{order.amount}"

ผลของตัวอย่างนี้ จะ return ค่าออกมาเป็น object ที่เป็นของ Order class หรือถ้าต้องการให้มันออกมาเป็นกลุ่มๆ

Order.find(:all, :conditions => "name='dave'") do |order|
  puts order.amount
end

หรือถ้าจะทำการ save(หรือ update, delete) อะไรลงใน database

Order.find(:all, :conditions => "name='dave&'") do |order|
  order.discount = 0.5
  order.save
end

นี่เป็นตัวอย่าง code เล็กๆ น้อยๆ

สำหรับ ORM library ทั่วๆ ไป การท่จะใช้งาน เราต้องมา configure อะไรอีกตั้งเยอะตั้งแยะ แต่ถ้าใช้ ORM tools ก็จะสบายหน่อย มีเครื่องไม้เครื่องมือ คอยช่วยสร้างตัว configuration(ส่วนใหญ่จะเห็นเป็น XML) ต่างๆ

Active Record

กว่าจะมาถึง Active Record ยืดยาวจริง Active Record คือ ชั้นของ ORM ของ Rails มีลักษณะเหมือนๆ กับ ORM model ทั่วๆ ไป คือ table จะ map เป็น class แล้ว row เป็น record แล้ว column เป็น attribute ของ object นั้นๆ แต่มันก็ต่างจาก ORM library ตัวอื่นๆ ตรงวิธีในการ configure เราจะทำการ configure มันตั้งแต่ตอนต่อกับ database เพียงทีเดียว แล้วมันจะจัดการให้หมดทุกอย่าง มาดูตัวอย่าง code ง่ายๆ สำหรับ Active Record

  1
  2
  3
  4
  5
  6
require "active_record"
class Order < ActiveRecord::Base
end
order = Order.find(1)
order.discount = 0.5
order.save

code นี้ จะทำการ new Order ขึ้นมาใหม่ แล้วทำการค้นหาโดย id แล้วทำการเซ็ตค่าให้กับ object(หรือ row) นั้นๆ แล้วทำการ save มันกลับลงไป แต่จริงๆ แล้ว Active Record ทำได้มากกว่านี้ ถ้าเราพัฒนางานบน Rails เรายังสามารถสั่งการ validate ข้อมูลได้อีกด้วย ถ้ามันมี error ก็ยังสามารถแสดง error นั้น ไปยังฝั่ง view ได้อีก ไว้มาดูตัวอย่างกันคราวหลัง

แก้ไขล่าสุด วันที่ 5 กรกฏาคม 2550 เวลา 1.44 น.

0 comments | Filed Under: Ruby on Rails | Tags: activerecord

codegent: we're hiring