Rails 4关系状态方法,这是最优的吗?

时间:2015-04-17 10:31:55

标签: ruby-on-rails ruby-on-rails-4

我正在Rails 4中构建社交网站。用户可以请求关注其他用户。

在我的用户模型中,我有以下方法。它有效,但我想知道这是否是确定关系状态的最佳方式。这个规模可以吗?

感谢。

def relationship_status(user_2)
  relationship = Relationship.where(follower_id: self.id, followed_id: user_2.id)
  unless relationship.any?
    relationship = Relationship.where(followed_id: self.id, follower_id: user_2.id)
    unless relationship.any?
      return "not_friends"
    else
      if relationship.first.status == "pending"
        return "pending_recieved"
      elsif  relationship.first.status == "ignored"
        return "you_ignored"
      elsif relationship.first.status == "active"
        return "your_followed"
      end
    end
  else
    if relationship.first.status == "pending"
      return "pending_sent"
    elsif relationship.first.status == "ignored"
      return "your_ignored"
    elsif relationship.first.status == "active"
      return "you_are_following"
    end
  end
end

2 个答案:

答案 0 :(得分:0)

这里没有任何明显不好的东西可以防止你在性能方面进行扩展。更大的扩展问题是你的代码的清晰度,以及当你需要在4个月后进行更改时你会多么讨厌自己,但是不记得你到底想要做什么了。

首先,您可能应该将确定关系性质的逻辑提取到Relationship类的方法中:

class Relationship
  def following_status
    case status
    when 'pending'
     'pending_sent'
    when 'ignored'
     'your_ignored'
    when 'active'
     'you_are_following'
    end
  end

  def followed_status
    case status
    when 'pending_received'
     'pending_sent'
    when 'you_ignored'
     'your_ignored'
    when 'active'
     'you_followed'
    end
  end
end

然后我们可以使用更有意义的变量名来清理关系状态方法:

def relationship_status(other_user)
  if following = Relationship.where(follower_id: self.id, followed_id: other_user.id).first
   return following.following_status
  end
  if followed = Relationship.where(followed_id: self.id, follower_id: other_user.id).first
    return followed.followed_status
  end
  'not_friends'
end

除此之外:Don't use unless and else together.这种形式读起来相当糟糕,并且非常令人眼花缭乱,尤其是在嵌套语句中。

答案 1 :(得分:0)

我不相信这会扩展得很好,因为你必须检查每个操作的每个关系。更好的方法是将它们扇出来并将它们放在更快的查询范围内

class User < ActiveRecord::Base
  has_many :user_relationships, dependent:destroy, inverse_of :user
  has_many :users, through: user_relationships
  has_many :affected_user_relationships, class_name: UserRelatonship, dependent:destroy, foreign_key :affected_id
  has_many :affected_users, through: user_relationships, source: :affected_user

  has_many :ignored_relationships, dependent:destroy, inverse_of :user
  has_many :ignored_users, through: ignored_relationships

  # etc... 
end

class UserRelationship
  belongs_to :user
  belongs_to :affected_user, class_name: User

  validates_presence_of :user, :affected_user
end

class IgnoredRelationship < UserRelationship
end

class FollowedRelationship < UserRelationship
end

然后你可以做更快的查询。

def ignored?(u)
  self.ignored_users.include?(u)
end