【发布时间】:2014-09-23 02:01:37
【问题描述】:
我创建了一个包含可搜索属性和分页的部分,以替换默认的 rails 脚手架索引视图。它在单个模型/控制器上运行良好,现在我的目标是以最干燥的方式与我的其他控制器共享这个部分。我的想法是应该有一种方法可以从控制器中指定要加载的视图,这样我就可以从所有控制器的 index 方法中加载相同的视图.我对其他解决方案持开放态度,只要它们是 DRY 或关于如何以更“轨道方式”更好地实现我的目标的建议。下面是我当前的工作实现,这需要我遍历大约 13 个模型并在每个索引方法中调用 super 并用下面的示例替换 index.html.erb 文件(这会产生 13 个相同的索引文件)。我希望能够在每个索引方法中执行以下操作并称其为好:
理想代码
def index
super
load_this_custom_page 'shared/index' # this is the line I'm looking for
end
当前代码
控制器:
def index
super
end
应用控制器:
include Modules::TableUI
def index
results = get_paged_search_results(params)
params = results[:params]
@instances = results[:instances]
end
modules.rb
module Modules
module TableUI
def get_paged_search_results(params)
params[:per_page] = 10 if params[:per_page].blank?
params[:page] = 1 if params[:page].blank?
unless params[:columns].blank? || params[:controller].blank?
model = eval(params[:controller].classify)
where_clause = ""
params[:columns].each do |name, value|
unless value.blank?
where_clause << "(#{model.table_name}.#{name} like '%#{value}%') AND "
end
end
where_clause << " (1=1)"
result_set = model.where(where_clause)
instances = model.paginate(page: params[:page] ,:per_page => params[:per_page]).merge(result_set)
return {instances:instances,params:params}
end
# there has got to be a better way to do this... I just can't find it
instances = eval(self.class.name.gsub("Controller","").singularize).page(params[:page])
return {instances:instances,params:params}
end
end
end
index.html.erb
<%= render :partial => 'shared/model_table',
:locals => {
:model => @instances.model,
:instances => @instances
}
%>
_model_table.html.erb
<h1><%= model.model_name.human.pluralize %></h1>
<%= form_tag("/#{model.model_name.route_key}", method: "get") do %>
Show <%= select_tag :per_page, options_for_select([ 10,25,50,100 ], params[:per_page]) %> entries
<%= hidden_field_tag(:page, params[:page]) %>
<%= submit_tag("Update table") %>
<table>
<thead>
<tr>
<% model.column_names.each do |name| %>
<th><%= model.human_attribute_name(name) %></th>
<% end %>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<tr>
<% instances.column_names.each_with_index do |attr, i| %>
<td><%= text_field_tag("columns[#{attr}]", params[:columns] ? params[:columns][attr] : nil) %></td>
<% end %>
</tr>
<% instances.each do |instance| %>
<tr>
<% instance.attribute_names.each do |attr| %>
<td><%= instance[attr.to_sym] %></td>
<% end %>
<td><%= link_to 'Show', instance %></td>
<td><%= link_to 'Edit', "/#{model.model_name.route_key}/#{instance.id}/edit" %></td>
<td><%= link_to 'Destroy', instance, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
<%= will_paginate instances %>
<br>
<%= link_to "New #{model.model_name.human}", "/#{model.model_name.route_key}/new" %>
【问题讨论】:
-
为什么不从控制器调用渲染?
-
完美的@Mohammad,正是我想要的。我最终将
render 'shared/index'放入controller#index 并删除了我所有的索引页。如果您关心投票,请创建一个答案,我会接受。
标签: ruby-on-rails routing dry templating partials