RailsSpace Pagination ใน Rails 2.2
ใน Listing 10.16 ของ RailsSpace เริ่มแนะนำการใช้งาน pagination หรือการแบ่งหน้าของผลลัพธ์ที่มาจากการ find หา record ในฐานข้อมูล แต่ว่าโค้ดดังกล่าวใช้ไม่ได้ใน Rails 2.2 และเราจะเจอ error แบบนี้:
NoMethodError in CommunityController#index
undefined method `paginate' for #<CommunityController:0x2532e7c>
ปัญหานี้เกิดขึ้นจากการที่ paginate ถูกย้ายออกไปเป็นปลั๊กอินแล้วตั้งแต่ Rails 2.0 ซึ่งหมายความว่าเราไม่มี method นี้ให้ใช้ใน 2.2
เลยลองหาดูว่ามีตัวเลือกอะไรนอกจาก classic_pagination ที่ระบุไว้ในเอกสารอ้างอิงบ้าง หาไปหามาก็เจอสองตัวเลือกคือ will_paginate และ paginator ซึ่งทั้งคู่เป็น gem ที่เราสามารถติดตั้งแล้วเอามาใช้ทดแทน paginate ใน Rails 2.0 ได้
เนื่องจากว่าในวิกิมีขั้นตอนแนะนำการติดตั้งอยู่ เลยลองใช้ will_paginate แทนดูซะ เพราะมีตัวอย่างอยู่ด้วย แรกๆลองใช้งานก็งงเล็กน้อย แต่ก็ถึงบางอ้อในเวลารวดเร็วเพราะใช้งานไม่ยากเลย คล้ายๆกับตัว paginate ที่มากับ Rails 2.0 แต่ง่ายกว่าซะด้วยซ้ำ
เจ้า will_paginate นี้จะทำการเพิ่ม method paginate ที่ทำงานได้เหมือนๆกับ find ของ ActiveRecord แค่คุณแทน find ด้วย paginate แล้วก็ส่ง argument ที่ method นี้ต้องการ ซึ่งก็คือเลขที่หน้าและจำนวนข้อมูลที่แสดงในแต่ละหน้า (ถ้าคุณไม่ระบุ will_paginate จะแสดง 30 record ในแต่ละหน้า)
ลองดูตัวอย่างทดแทน Listing 10.16 กัน:
def index
...
if params[:id]
@initial = params[:id]
@specs = Spec.paginate(:conditions => ["last_name LIKE ?", @initial+'%'],
:order => "last_name, first_name",
:page => params[:page] || 1,
:per_page => 5)
@users = @specs.collect { |spec| spec.user }
end
end
ใน controller ก็ง่ายๆแค่นี้แหละ อย่างที่บอกคือ will_paginate จะเพิ่ม helper method เข้าไปใน model ของเรา ทำให้เราสามารถเรียกใช้ paginate ได้เลย ในตัวอย่างเราจะแสดงเลขที่หน้าที่ระบุใน parameter ของ web request หรือ 1 ถ้าไม่ได้ระบุ และแสดงหน้าละ 5 record (ถ้าคุณใช้ will_paginate ใน view ตัวแปร :page จะถูกเซ็ตไว้ใน parameter ของ request โดยอัตโนมัติ)
ส่วนใน view เราจะแก้ไขใน user_table partial โดยแทนที่ pagination_links ด้วย will_paginate เท่านี้ก็เรียบร้อย
<% if @users and not @users.empty? %> <table class="users" border="0" cellspacing="1" cellpadding="5"> ... <tr> <td colspan="4" align="right"> <%= will_paginate @specs, :params => params %> </td> </tr> </table> <% end %>