在Rails项目中我们有时为了某些需要,可以创建一些不和实际Model关联的Controller,这称之为”虚控制器”.
这些控制器的主要功能是辅助普通控制器完成一些常规方法比较难实现的功能,比如search.
做过model搜索功能的童鞋可能知道,在Object#index中集成search,然后再开分页,那简直就是一团糟… ;(
所以我们索性将一般Model对象的搜索功能单独放在一个模块中.但是又不能放在独立的Module中,因为它们没有对应的View,所以不如创建Object对应的ObjectSearchController来辅助完成搜索功能.
但是在用这些辅助序控制器类时,我们往往会给实际的分页对象一个不同的名字,比如:
def search_results
if @@last_search_results
@staffs = @@last_search_results.paginate(page:params[:page])
end
end
然后在视图中就会报错:
Completed 500 Internal Server Error in 43ms
ActionView::Template::Error (The @staffs_search variable appears to be empty. Did you forget to pass the collection object for will_paginate?):
7: <ul class="users">
8: <%= render @staffs%>
9: </ul>
10: <%= will_paginate %>
11: </div>
app/views/staffs_search/search_results.html.erb:10:in `_app_views_staffs_search_search_results_html_erb__3662154376169114384_70323387533080'
app/controllers/staffs_search_controller.rb:13:in `search'
这是因为视图中的will_paginate方法默认一个与Action所在控制器相同的Model名称,这和我们修改过的名称不一致了,所幸的是我们可以手动赋予一个指定的参数:
<div>
<%= will_paginate(@staffs) %>
<ul class="users">
<%= render @staffs%>
</ul>
<%= will_paginate(@staffs) %>
</div>
现在一切都正常了.