2011-08-27 98 views
4

所以我正在構建一個匹配用戶的應用程序。用戶模型有3個屬性(即有關我的問題反正:gender:stringlooking_for_men:booleanlooking_for_women:boolean複雜的範圍,Rails 3

目前我有一個方法,在我的模型,像這樣:

def browse 
    if self.looking_for_men == true && self.looking_for_women == true 
    if self.sex == "Male" 
     User.where("looking_for_men = ?", true) 
    elsif self.sex == "Female" 
     User.where("looking_for_women = ?", true) 
    end 
    elsif self.sex == "Male" && self.looking_for_men == true 
    User.where("looking_for_men = ? AND sex = ?", true, "Male") 
    elsif self.sex == "Female" && self.looking_for_women == true 
    User.where("looking_for_women = ? AND sex = ?", true, "Female") 
    else 
    if self.sex == "Male" 
     User.where("looking_for_men = ? AND sex = ?", true, "Female") 
    elsif self.sex == "Female" 
     User.where("looking_for_women = ? AND sex = ?", true, "Male") 
    end 
    end 
end 

這是相當混亂,如你可以告訴我們有沒有辦法清理這個問題,並把它變成一個範圍,比如說我是一個男性用戶,並且我正在尋找女性,它只會返回在我查詢時正在尋找男性的女性像這樣:

@users = User.all.browse 

回答

5

我只是做下面的代碼,使其更具可讀性。但不知何故,我對這個解決方案並不完全熟悉。還有很多代碼:

class User < ActiveRecord::Base 
    scope :male, where(:gender => "Male") 
    scope :female, where(:gender => "Female") 
    scope :looking_for_men, where(:looking_for_men => true) 
    scope :looking_for_women, where(:looking_for_women => true) 

    def browse 
    @women = @men = [] 

    @women = self.interested_females if self.looking_for_women 
    @men = self.interested_males if self.looking_for_men 

    @result = @women.concat(@men) 
    @result.delete(self) #removes the user itself from the result-set 

    return @result 
    end 

    def interested_females 
    return User.female.looking_for_men if self.male? 
    return User.female.looking_for_women if self.female? 
    end 

    def interested_males 
    return User.male.looking_for_men if self.male? 
    return User.male.looking_for_women if self.female? 
    end 

    def male? 
    return (self.gender == "Male") 
    end 

    def female? 
    return (self.gender == "Female") 
    end 
end 
+1

我喜歡這個。爲了可讀性,我會重命名範圍'looking_for_men'和'looking_for_women'(與布爾值相沖突);但那不是真的需要。 – nathanvda

1

從範圍的角度來看,只需將它傳遞給proc,就可以將該邏輯輕鬆移入範圍。

class User 
    scope :browse_for, lambda { |user| 
     user.looking_for_men == true && user.looking_for_women == true 
     ... 
    } 
end 

@users = User.browse_for(@single_male) 

,你也可以連鎖範圍,共同清理邏輯:http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/the-skinny-on-scopes-formerly-named-scope/index.html

我不確定這是否能回答您的問題?