2011-12-14 7 views
0

私のモデルには、管理パネルのフィルタである必要があるいくつかのスコープがあります。ActiveRecordスコープをfilter_by文字列として渡す

Filter by: <a href="?filter_by=archived_newspaper">Archived Newspapers</a> 
    <a href="?filter_by=current_magazine">Current Magazines</a> 

periodical.rb

class Periodical < ActiveRecord::Base 
    scope :archived_newspaper, where("category = 'Newspaper'").where("archived = ?", true) 
    scope :current_magazine, where("category = 'Magazine'").where("archived = ?", false) 
end 

index.html.erbはどのようになど、ソート改ページ、検索、などの他の典型的なものがあるだろうことを考えると、コントローラを実装するのでしょうか?

class PeriodicalController < ApplicationController 
    def index 
    @periodicals = Periodical.page(params[:page]) 
    @periodicals = @periodicals.order(params[:sort_by]) if !params[:sort_by].blank? 
    # Scope here 
    end 
end 

答えて

2

は、私はそれで確かにセキュリティ上の問題があるので、これが最善の解決策があるかどうかわからないんだけど、あなたはこのような何か行うことができます:

class PeriodicalController < ApplicationController 
    def index 
    @periodicals = Periodical.page(params[:page]) 
    @periodicals = @periodicals.order(params[:sort_by]) unless params[:sort_by].blank? 

    if params[:filter_by] and Periodical.respond_to?(params[:filter_by].to_sym) 
     begin 
     new_scope = Periodical.send(params[:filter_by].to_sym) 
     new_scope = nil unless new_scope.is_a?(ActiveRecord::Relation) 
     rescue ArgumentError 
     new_scope = nil 
     end 
     @periodicals.merge(new_scope) 
    end 
    end 
end 

EDIT:いくつかの選択肢を:

1)許容範囲のリストにパラメータをフィルタリングします(リクエスト内のパラメータを編集する人による攻撃から定期モデルをよりよく保護します)

filter_by = params[:filter_by].to_sym 
if [:archived_magazine, :current_magazine].include?(filter_by) 
    new_scope = Periodical.send(params[:filter_by].to_sym) 
    @periodicals.merge(new_scope) 
end 

2)より優れたセキュリティ(スコープケース/スイッチとハードコードを使用していますが、非常に乾燥していない)

new_scope = case params[:filter_by] 
    when "archived_magazine" 
    Periodical.archived_magazine 
    when "current_magazine" 
    Periodical.current_magazine 
    else 
    nil 
end 
@periodicals.merge(new_scope) 
+0

いやがsend私が神経質になります... –

+1

ええ、私は最大ではありませんよファン、しかしそれを合理的にうまく保護することができます、彼らは私がそれだけでfilter_by paramは、周期モデルからアーリースコープのメソッドを0にすることができますコード化しました。他の唯一の方法は、許容されるfilter_by値をコントローラに明示的にコーディングし(そして依然として送信を使用する)、またはケース/スイッチを使用してスコープをハードコードすることです。私は何を意味するのかを編集するでしょう –

+1

@世紀に送ることは神経質にならないはずです。これはRubyの一部であり、有用なものです。メソッドがparamsを取らず、paramsでメソッドを送信しないようにしてください。セキュリティ上の懸念はありません。 –

関連する問題