我想做一个通用网格,可以在我的应用程序中用来显示来自不同模型的数据。因为我是RoR的新手 - 如果我的“愿景”没问题,请告诉我,否则我应该改变我对这个问题的看法:
控制器:
class Admin::UsersController < ApplicationController
before_action :authenticate_user!
authorize_resource
def index
@current_scope = params[:role]
@users = User.select(:id, :email, :role, :last_sign_in_at).role(@current_scope)
end
end
用户模型:
scope :role, -> (role) {where('role = ?', role) if role.present?}
索引视图:
<%= render '/layouts/shared/grid', object: @users%>
网格部分:
<% object.column_names.each do |column_name| %>
<th><%= column_name %></th>
<% end %>
我的问题是我可以显示所有列(这是ActiveRecord :: Relation返回的列),而不仅仅是我的查询中选择的参数列。我看到几个潜在的解决方案 - 哪一个最好?
使用ActiveRecord :: Base.connection.exec_query - 如果我这样做,我可以使用then .columns方法返回我需要的东西。但我不确定我是否喜欢它......
使用search_params代替查询结果进行迭代
还有其他建议吗?
答案 0 :(得分:0)
您可以使用URL
方法。它没有很好的文档,但它返回解析的SQL查询。
对于此查询:
values
它返回如下内容:
User.select(:id, :email, :role,:last_sign_in_at).role(@current_scope).values
如果{:select=>[:id, :email, :role, :last_sign_in_at], :where=>#<ActiveRecord::Relation::WhereClause:0x007fe0d3b29bf0 @predicates=["role = admin"], @binds=[]>}
在select
也不会返回values
结果时查询将不会使用select
。在这种情况下,您需要使用column_names
。
我可以建议你将表格代码包装到装饰者。这是一个原始的例子:
class TableDecorator
def initialize(scope)
@scope = scope
end
def header_columns
scope.values[:select] || @scope.column_names
end
def columns
@scope
end
end
# controller
@table = TableDecorator.new(@users)
# index view
<%= render '/layouts/shared/grid', locals: {table: @table} %>
# grid partial
<table>
<thead>
<tr>
<% table.header_columns.each do |column_name| %>
<th><%= column_name %></th>
<% end %>
</tr>
</thead>
<tbody>
<% table.columns.each do |item| %>
<tr>
<% table.header_columns.each do |column_name| %>
<td><%= item[column_name] %></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>