rails5:通用网格 - 如何获取当前搜索的列名

时间:2017-01-20 20:57:04

标签: ruby-on-rails

我想做一个通用网格,可以在我的应用程序中用来显示来自不同模型的数据。因为我是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返回的列),而不仅仅是我的查询中选择的参数列。我看到几个潜在的解决方案 - 哪一个最好?

  1. 使用ActiveRecord :: Base.connection.exec_query - 如果我这样做,我可以使用then .columns方法返回我需要的东西。但我不确定我是否喜欢它......

  2. 使用search_params代替查询结果进行迭代

  3. 还有其他建议吗?

1 个答案:

答案 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>