เขียน blog บน Merb
posted on 28 Dec 2008 16:20 by wonam in softdevผมได้ทดลองใช้ merb เมื่อสองสามวันก่อน อย่างไรก็ตามหลังจากได้ทดลองหาตัวอย่างที่จะได้หัดตามจากอินเทอร์เน็ต กลับพบว่าตัวอย่างพวกนั้นเก่าเกินไปแล้ว หรือไม่ก็ไม่ได้ใช้ Datamapper เป็น ORM เหมือนที่ผมต้องการทดลองเล่น
แน่นอนว่าผมทราบข่าว Merb 2 = Rails 3 แล้ว และนี่ก็เป็นสาเหตุที่เอา Merb มาหัด เพราะว่าอยากเล่น Merb สักหน่อยก่อน จะได้ทราบว่าอะไรที่มันน่าจะน่าสนใจบ้าง
บทความนี้เอาขั้นตอนหลัก ๆ มาจากบทความ "merb + datamapper + noob: quick start" แต่ตัดบางอย่างออก และปรับการใช้งานให้ตรงกับ Merb เวอร์ชั่นที่ผมใช้อยู่ (1.0.6) นอกจากนี้ยังคาดว่าผู้อ่านน่าจะมีประสบการณ์การใช้ Rails มาบ้างครับ
ขั้นแรกคือติดตั้ง merb ถ้าเป็น ubuntu ก็ทำประมาณ
$ sudo gem install merb
$ sudo gem install datamapper merb_datamapper do_sqlite3
$ merb-gen app blog
ใน blog/ จะมีโครงสร้างของไดเร็กทอรีที่ผู้ใช้ Rails น่าจะคุ้นเคย ไฟล์ที่เกี่ยวข้องกับการตั้งค่าจะอยู่ในไดเร็กทอรี config/ ไฟล์ที่น่าสนใจก็มีเช่น dependencies.rb (ระบุว่าใช้โมดูลไหนบ้าง --- การถอดประกอบเป็นจุดเด่นของ merb), init.rb (ใช้ระบุว่าจะเลือกใช้อะไรเป็น ORM, เป็นระบบทดสอบ และระบบ template), และ database.yml (เช่นเดียวกับใน Rails ที่ระบุข้อมูลเกี่ยวกับฐานข้อมูลที่ใช้).
ในขั้นนี้ของที่ merb สร้างมาให้น่าจะโอเคแล้ว เราก็จะใช้ไปตามนั้นก่อน
สร้างโมเดล
ได้เวลามาสร้างโมเดลกันครับ สั่งคำสั่งด้านล่าง (ในไดเร็กทอรี blog/)
$ merb-gen model post
ในการพัฒนาใน Rails เราจะเขียนเพียงแค่ migration จากนั้นข้อมูลเกี่ยวกับโมเดลจะถูกอ่านจากตารางในฐานข้อมูล แต่ในการพัฒนาด้วย Datamapper นั้นเราจะระบุข้อมูลของโมเดล เช่นพวก property ในคลาสเลย ดังนั้นแก้ไฟล์ post.rb ให้เป็น
class Post include DataMapper::Resource property :id, Serial property :title, String property :body, String endหลังจากนั้นเราจะต้องจัดการสร้างตารางของโมเดลในฐานข้อมูล ในกรณีที่เราปรับเปลี่ยน property ง่าย ๆ (เช่น สร้างโมเดลหรือเพิ่ม property) merb สามารถจะปรับตารางให้เราได้โดยไม่ต้องเขียน migration เลย โดยเราสามารถเรียก
$ rake db:autoupgrade
เมื่อสร้างเสร็จแล้ว เราจะลองเล่นใน interactive console ของ merb ก่อน เพื่อใส่ post ลงไปหลาย ๆ อันให้เรามีข้อมูลแสดงนะครับ เรียก interactive console โดยสั่ง
$ merb -i
irb(main):001:0> p1 = Post.new
irb(main):002:0> p1.title = 'Hello'
irb(main):003:0> p1.body = 'This is my first post'
irb(main):004:0> p1.save
~ INSERT INTO "posts" ("title", "body")
VALUES ('Hello!', 'This is my first post')
=> true
irb(main):001:0> p2 = Post.new
irb(main):002:0> p2.title = 'Second post'
irb(main):003:0> p2.body = 'Here I post again'
irb(main):004:0> p2.save
~ INSERT INTO "posts" ("title", "body")
VALUES ('Second post', 'Here I post again')
=> true
สร้างคอนโทรเลอร์
ตอนนี้เราก็มีข้อมูลพอจะให้แสดงได้แล้ว ไปสร้างคอนโทรเลอร์กันครับ เรียกคำสั่ง
$ merb-gen controller posts
เข้าไปเพิ่มให้เมท็อด index ค้น post ทั้งหมดออกมาครับ
class Posts < Application
def index
@posts = Post.all
render
end
end
สังเกตว่าใน merb ทุกครั้งที่ทำงานเสร็จเราจะต้องเรียกเมท็อด render ให้แสดง view เอง (ใน rails จะทำให้อัตโนมัติ) การเรียกดังกล่าวจะนำ view สำหรับเมท็อดนี้มาแสดง ข้อสังเกตอีกประการคือเราเรียก Post.all แทนที่จะเป็น Post.find(:all) เหมือนตอนที่เขียนด้วย Active Record
จากนั้นไปสร้าง view เพื่อแสดงผล post กันครับ ไปแก้ไฟล์ views/posts/index.html.erb ให้เป็นดังนี้ครับ
<h1>My posts</h1> <% for post in @posts %> <h2><%= post.title %></h2> <p><%= post.body %></p> <% end %>
$ merb
เพิ่ม post ใหม่
ไปสร้างหน้าสำหรับป้อน post ใหม่กันครับ เราจะเพิ่มลิงก์ "add new post" ที่ด้านล่างของหน้า index ครับ โดยเติม คำสั่งด้านล่างเข้าไปใน index.html.erb ครับ
<%= link_to 'add new post', url(:controller => :posts,
:action => :new) %>
จากนั้นไปสร้างเมท็อด new ในคอนโทรเลอร์ Posts ที่แสดง view สำหรับแสดงฟอร์มครับ
class Posts < Application
# ...
def new
@post = Post.new
render
end
end
แล้วก็ไปสร้าง view new.html.erb ในไดเร็กทอรี app/views/posts:
<h1>Creating new post</h1> <%= form_for @post, :action => 'create' do %> <%= text_field :title, :label => 'Title' %><br/> <%= text_area :body, :label => 'Body' %><br/> <%= submit 'New post' %> <% end =%>
สุดท้ายเราก็ไปเพิ่มเมท็อด create ลงไปในคอนโทรเลอร์ Posts เพื่อสร้าง post ใหม่ครับ
class Posts < Application
# ...
def create
@post = Post.new params[:post]
@post.save
redirect url(:action => 'index')
end
end
ลองทดลองดูนะครับว่าสามารถเพิ่ม post ได้หรือไม่ครับ
ระบบความเห็น
ระบบ blog คงไม่มีความหมายถ้าไม่สามารถใส่ comment ได้
เราจะสร้างโมเดล comment โดยเรียก
$ merb-gen model comment
class Comment include DataMapper::Resource property :id, Serial property :body, String end
จากนั้นเราต้องไประบุในโมเดล Post ถึงการเชื่อมโยงกับโมเดล Comment เราทำโดยระบุ has ลงไปในไฟล์ app/models/post.rb
class Post # ... has n, :comments endการสั่งดังกล่าวจะมีลักษณะคล้าย ๆ กับสั่ง has_many ใน Active Record ถ้าต้องการความสัมพันธ์แบบ one-to-one สามารถสั่ง has 1, :comment แทนได้ครับ
จากนั้นไปปรับ view โดยแก้ app/views/posts/index.html.erb ให้แสดง comment และมี comment form ครับ
<h1>My posts</h1>
<% for post in @posts %>
<h2><%= post.title %></h2>
<p><%= post.body %></p>
<ul>
<% post.comments.each do |comment| %>
<li><%= comment.body %></li>
<% end %>
<li>
<%= form_for Comment.new,
:action => url(:controller => 'posts',
:action => 'create_comment',
:id => post.id) do %>
<%= text_field :body %>
<%= submit 'New comment' %>
<% end =%>
</li>
</ul>
<% end %>
<%= link_to 'add new post', url(:controller => :posts,
:action => :new) %>
จากนั้นเราไปสร้างเมท็อด create_comment ในคอนโทรเลอร์ Posts
class Posts < Application
# ...
def create_comment
post = Post[params[:id]]
comment = Comment.new params[:comment]
post.comments << comment
post.save
redirect url(:action => 'index')
end
end
สังเกตว่าเราสามารถสั่ง Post[params[:id]] เพื่อเรียก post ที่มี id ตามที่ระบุได้
หวังว่าเอนทรีนี้น่าจะเป็นประโยชน์สำหรับผู้กำลังจะหัด merb และ Datamapper บ้างนะครับ ถ้ามีตำแนะนำคำแนะนำอะไรรบกวนใส่ด้านล่างเลยนะครับ
หมายเหตุ: English version

เห็นแล้วอยากจะปั่น merb66 ให้เสร็จโดยไว
#1 By PunNeng (58.8.116.152) on 2008-12-28 21:49