Tik’s Blog

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

ArgumentError in Community#search ใน RailsSpace

leave a comment »

สงครามยังไม่จบอย่าพึ่งนับศพทหาร…แก้บั๊กที่แล้วไปแป๊ปเดียว เจออันใหม่อีกแล้ว

หลังจากเราแก้ไขให้ will_paginate ทำงานได้ ปรากฏว่าพอทำตาม Listing 11.9 หน้า 336 ก็เจอปัญหาใหม่ ประมาณว่าพอเราค้นหาคำปุ๊ปจะเจอ error ว่า

  ArgumentError in Community#search
  Showing app/views/community/_user_table.html.erb where line #16 raised:
  The @community variable appears to be empty. Did you forget to pass the collection
    object for will_paginate?

จริงๆแล้วโค้ดตรงนี้ก็ไม่ใช่ปัญหาเท่าไร  ปัญหาจริงๆอยู่ที่ว่าเราต้องใช้โค้ดใน Listing 11.10 เพื่อเพิ่ม method ให้ทำงานได้ แต่ว่า Listing 11.10 มันเข้ากันไม่ได้กับ will_paginate และ Paginator ก็ไม่มีใน Rails 2.3 แล้วด้วย เพราะงั้นเราต้องเขียนโค้ดทดแทนที่ทำงานกับ will_paginate ได้แทน

คุ้ยๆโค้ด will_paginate ดู ได้โค้ดทดแทนก็ประมาณนี้ (โค้ดค่อนข้างห่วย แต่เวิร์คไปก่อน + โค้ดนี้เป็นโค้ดต่อท้ายใน method search ของ community_controller.rb เพราะยังไม่รู้จะทำให้เป็น generic ยังไง)

  def search
    @title = "Search RailsSpace"
    if params[:q]
       ...

      # Now combine into one list of distinct users sorted by last name.
      ...

      # Manual pagination.
      hit_specs = @users.collect { |user| user.spec }
      page = params[:page] || 1
      @specs = WillPaginate::Collection.create(page, 5, hit_specs.count) do |pager|
        pager.replace(hit_specs)
      end
      @users = WillPaginate::Collection.create(page, 5, @users.count) do |pager|
        pager.replace(@users)
      end
      @specs = @specs.paginate(:page => page, :per_page => 5)
      @users = @users.paginate(:page => page, :per_page => 5)
    end
  end

เท่านี้ก็เรียบร้อย กล้อมแกล้มให้ทำงานได้ไปก่อน ค่อยหาวิธีทำให้โค้ดสวยขึ้นเมื่อความรู้เพิ่มขึ้น

อธิบายโค้ดคร่าวๆ:

  • สร้าง @specs ขึ้นมาเพราะ _user_table partial ต้องใช้ส่งให้ will_paginate และเซ็ตค่าให้เป็น specs เฉพาะในหน้าที่ระบุเท่านั้น (เพราะ first_item และ last_item ใน _result_summary partial ต้องใช้)
  • สร้าง @users และเซ็ตค่าให้เป็นเฉพาะ users ที่อยู่ในหน้าที่ระบุเท่านั้นเพราะ _user_table partial ต้องใช้ คล้ายๆกับ @specs แหละ
  • method create ของ WillPaginate::Collection จะทำการสร้าง collection ใหม่ที่จะครอบ @specs/@users โดยสนับสนุนการแบ่งหน้าในตัว (method paginate ก็เป็น method ที่ define ใน will_paginate gem)

Written by sukita

เมษายน 8, 2009 ที่ 10:13 pm

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

Tagged with

ใส่ความเห็น