2017-01-20 7 views
1

私は、別のモデルのデータを表示するために私のアプリで使用することができる汎用グリッドを行うことを望みます。私はRoRのでは初心者ですとして - 私の「ビジョン」がOKであれば、私に知らせて、または私はこの問題について考える方法を変更する必要がありますしてくださいrails5:一般的なグリッド - 現在の検索の列名を取得する方法

コントローラー:

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?} 

Indexビュー:パーシャル

<%= 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の

  1. 使い方 - 私はそうするならば、私はその後、私は必要なものを返す.columnsメソッドを使用することができます。しかし、私が代わりにクエリ結果のsearch_paramsの

  2. 使用量が

その他の提案反復するために...私はそれを好きかどうかわからないのですか?

答えて

0

valuesメソッドを使用できます。それは非常に文書化されていませんが、解析されたSQLクエリを返します。このクエリの

valuesがあまりにもselect結果を返さないとき、クエリがselectを使用しない場合は

{:select=>[:id, :email, :role, :last_sign_in_at], :where=>#<ActiveRecord::Relation::WhereClause:0x007fe0d3b29bf0 @predicates=["role = admin"], @binds=[]>} 

User.select(:id, :email, :role,:last_sign_in_at).role(@current_scope).values 

それはこのような何かを返します。この場合、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> 
+0

Thx!私はあなたのソリューションが好きです - もっとクリーンな私の:) Unfortunatelly私は今日私のアプリでそれを行う時間がありません - しかし、私はすぐに私はそれを行うにはここで短い更新を行うことを約束:) – MaciekR

+0

あなたはここでデコレータパターンを使用します。私は同意します - それは理にかなっています(動的グリッドコントロールを生成したコードを、グリッドにデータで埋め込んだコードから分割しました)。私は前にレールにデコレータパターンを使用したことはありません - あなたがデコレータを使用したい場合は、ドレープの宝石を使用し、それを「デフォルト」に含めることは理にかなっていると思いますか? – MaciekR

+0

はい、ドラッパーはこれに適しています。それを試してみてください。 –

関連する問題