2011-08-10 54 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 

我想我只會得到最後,即使所有「如果」是真的。

我是對的嗎?

回答

1

如果我理解你的要求,你只要應用的每個範圍是否存在一種條件......你可以使用一個名爲範圍是lambda,然後把它們連:

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


@people = Person.one(true).two(false) 
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我可以建議唯一的方法在這裏鏈(如simmilar做@socjopata(:

# 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

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

然後:

Model.conditional_scope 
0

也許你正在尋找一種方式,以避免明確每where條款後分配新範圍是什麼?你可能對這個railscast感興趣:http://railscasts.com/episodes/212-refactoring-dynamic-delegator。瑞安貝茨使用委託人來實現這樣的代碼:

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