2011-08-10 16 views
1
@people = People.scoped 
@people = @people.where(...) if ... 
@people = @people.where(...) if ... 
@people = @people.where(...) if ... 
@people = @people.where(...) if ... 

をリファクタリング支援する任意のルビー既存のソリューションは私はルビー次のコード

@people = People.scoped 

@people.???? do 
    where(...) if ... 
    where(...) if ... 
    where(...) if ... 
end 

PSのようなものを作ることです:答えてくれてありがとう。しかし、あなたが提供するソリューションは次のようになります

def self.conditional_scope 
    where(...) if ... 
    where(...) if ... 
    where(...) if ... 
end 

"if"がすべて真であっても最後になると思います。

私は正しいですか?

答えて

1

私はあなたが求めているものを理解していれば、あなただけの条件が存在する場合、各スコープを適用したい...、と:

その後
1

はい。あなただけのモデルに移動する必要があります。

明らか
# Controller 
@people = People.find_my_guy 

# Model 
def self.find_my_guy 
    where(...) if ... 
    where(...) if ... 
    where(...) if ... 
end 

、あなたは彼らがあなたの文で使用されている場合は、あなたのモデルにいくつかの環境変数を渡す必要があります:

# Controller 
@people = People.find_my_guy(params) 

# Model 
def self.find_my_guy(params) 
    where(:id => params[:id]) if params[:id] 
    where('title LIKE (?)', "%#{params[:search]}%") if parmas[:search] 
    where(...) if ... 
end 

限り、あなたのように」最後whereに関する権利再私はここに連鎖する唯一の方法を提案することができ@socjopataが行ったように(simmilar(:

# Model 
def self.with_name(name) 
    where(:name => name) if name.present? 
end 

def self.with_id_gt(id) 
    where('id >= ?', id) if id.to_i > 3 
end 

# Controller 
Post.with_name(parms[:name]).with_id_gt(params[:id]) 
+0

もう一度同意したようです。 +1 :) – apneadiving

+0

この解決方法は最後に戻ります。私は連鎖が必要です。私は正しい? – randx

+0

@randx、回答を更新しました – fl00r

2

私はあなたがnamed_scopesと自分が慣れる必要があると思う: http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html

彼らは構成可能なので、あなたのような何かを書くことができます。

People.tall.having_children.older_than(30) 

"背の高い"、 "having_children" と "older_than" と命名されているスコープを。あなたは、ラムダと名前のスコープを使用することができ

Model.conditional_scope 
1
def self.conditional_scope 
    where(...) if ... 
    where(...) if ... 
    where(...) if ... 
end 

それらをチェーン:

scope :one, lambda {|condition| condition ? where(...) : {}} 
scope :two, lambda {|condition| condition ? where(...) : {}} 
... 


@people = Person.one(true).two(false) 
0

はたぶん、あなたは明示的にすべてのwhere句の後に新しい範囲を割り当てないようにする方法を探していますか?あなたはこのレールキャストに興味があるかもしれません:http://railscasts.com/episodes/212-refactoring-dynamic-delegator。 Ryan Batesは次のようなコードを達成するために委任者を使用します:

def self.search(params) 
    products = scope_builder 
    products.where("name like ?", "%" + params[:name] + "%") if params[:name] 
    products.where("price >= ?", params[:price_gt]) if params[:price_gt] 
    products.where("price <= ?", params[:price_lt]) if params[:price_lt] 
    products 
end 
関連する問題