Tik’s Blog

ร้อยแปดพันเก้า

RailsSpace Pagination ใน Rails 2.2

leave a comment »

ใน 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 %>

Written by sukita

มีนาคม 12, 2009 ที่ 10:07 pm

บันทึกโพสใน Programming

Tagged with

ใส่ความเห็น