2011-08-27 62 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

我不确定这是否能回答您的问题?