So I am building an application that matches users.  User models have 3 attributes (that are relevant to my question anyways: gender:string, looking_for_men:boolean, looking_for_women:boolean.
currently I've got a method in my model like so:
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
This is pretty messy, as you can tell. Is there anyway to clean this up and make it into a scope, so that say for example I am a male user, and I am looking for women that it returns only women who are looking for men when I do a query like so:
@users = User.all.browse
                I would just do the code below, to make it more readable. But somehow,I'm not totally comfortable with this solution. Still lot of code:
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
                        Just from a scope point of view, you could move that logic into a scope fairly easily just by passing it to a 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)
and you could also chain scopes together to clean up the logic: http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/the-skinny-on-scopes-formerly-named-scope/index.html.
I'm not sure if that quite answers your question?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With