I'm building a social site in Rails 4. Users can request to follow another user.
我正在Rails 4中创建一个社交站点。用户可以请求跟踪另一个用户。
In my user model I have the following method. It works but I'm wondering if it is the best way to do determine the relationship status. Will this scale okay?
在我的用户模型中,我有以下方法。它是有效的,但我想知道这是否是确定关系状态的最好方法。这个规模会更大?
Thanks.
谢谢。
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 个解决方案
#1
0
I don't believe this will scale very well as you will have to check each relationship for each operation. The better approach would be to fan them out and scope them for faster queries
我不相信这将会很好,因为你将不得不检查每一个关系的每一个操作。更好的方法是将它们扇出,并使它们适用于更快的查询。
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
Then you could do faster queries.
然后您可以执行更快的查询。
def ignored?(u)
self.ignored_users.include?(u)
end
#2
0
There's nothing glaringly bad here that will prevent you from scaling with respect to performance. The bigger scaling issue is your code's clarity, and how much you'll hate yourself when you need to make a change here 4 months from now, but can't remember what the hell you were trying to do here.
这里没有什么可怕的东西可以阻止你对性能的扩展。更大的问题是你的代码的清晰性,当你需要在4个月后做出改变的时候,你会多么憎恨自己,但却不记得你在这里到底想做什么。
First, you should probably extract the logic that determine the nature of relationship into methods on your Relationship class:
首先,你应该从关系类的方法中提取确定关系性质的逻辑:
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
Then we can clean up the relationship status method using more meaningful variable names:
然后我们可以使用更有意义的变量名来清理关系状态方法:
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
Aside: Don't use unless
and else
together. That form reads rather poorly, and gets very dizzying, especially in nested statements.
旁白:除非和其他一起使用,否则不要使用。这个表单读起来相当糟糕,而且非常令人头晕,尤其是在嵌套语句中。
#1
0
I don't believe this will scale very well as you will have to check each relationship for each operation. The better approach would be to fan them out and scope them for faster queries
我不相信这将会很好,因为你将不得不检查每一个关系的每一个操作。更好的方法是将它们扇出,并使它们适用于更快的查询。
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
Then you could do faster queries.
然后您可以执行更快的查询。
def ignored?(u)
self.ignored_users.include?(u)
end
#2
0
There's nothing glaringly bad here that will prevent you from scaling with respect to performance. The bigger scaling issue is your code's clarity, and how much you'll hate yourself when you need to make a change here 4 months from now, but can't remember what the hell you were trying to do here.
这里没有什么可怕的东西可以阻止你对性能的扩展。更大的问题是你的代码的清晰性,当你需要在4个月后做出改变的时候,你会多么憎恨自己,但却不记得你在这里到底想做什么。
First, you should probably extract the logic that determine the nature of relationship into methods on your Relationship class:
首先,你应该从关系类的方法中提取确定关系性质的逻辑:
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
Then we can clean up the relationship status method using more meaningful variable names:
然后我们可以使用更有意义的变量名来清理关系状态方法:
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
Aside: Don't use unless
and else
together. That form reads rather poorly, and gets very dizzying, especially in nested statements.
旁白:除非和其他一起使用,否则不要使用。这个表单读起来相当糟糕,而且非常令人头晕,尤其是在嵌套语句中。