我正在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
答案 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