ArgumentError in Community#search ใน RailsSpace
สงครามยังไม่จบอย่าพึ่งนับศพทหาร…แก้บั๊กที่แล้วไปแป๊ปเดียว เจออันใหม่อีกแล้ว
หลังจากเราแก้ไขให้ 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)