我有一个名为Block
的模型,其中包含blocker_id
(user_id)和blocked_user_id
字段(也是user_id)。 Block
模型允许一个用户阻止另一个用户。当一个用户阻止另一个用户时,我希望它使用Relationship
类的before_save
方法销毁它们之间的Block
。 Relationship
表格包含follower_id
和followed_id
。
这是事情变得棘手的地方。我知道我可以通过使用多个return if Relationship.xyz.nil?
语句然后使用多个Relationship.find_by(follower_id: , followed_id: ).destroy
语句来实现此目标,但这会变得复杂,因为每个blocker
和blocked_user
都可以follower
和followed
id,两者都有,或者两者都没有。有没有更简单的方法呢?
这是我的模型供参考:( Block
课程也有一个blocked_post
字段,我没有遇到任何问题)
class Block < ActiveRecord::Base
validates :blocker_id, presence: true
validates :blocked_user_id, uniqueness: {scope: :blocker_id}, allow_nil: true
validates :blocked_post_id, uniqueness: {scope: :blocker_id}, allow_nil: true
validate :blocked_user_or_post
after_validation :validate_block
before_save :destroy_blocked_relationships
belongs_to(
:blocker,
class_name: "User"
)
has_one(
:blocked_user,
class_name: "User"
)
has_one(
:blocked_post,
class_name: "Post"
)
private
def blocked_user_or_post
blocked_user_id.blank? ^ blocked_post_id.blank?
end
def validate_block
if blocked_user_id.present?
!(blocker_id == blocked_user_id)
elsif blocked_post_id.present?
blocked_post = Post.find_by(id: self.blocked_post_id).user_id
!(blocker_id == blocked_post)
else
false
end
end
def destroy_blocked_relationships
#my over-complex code was here
end
end
relationship.rb:
class Relationship < ActiveRecord::Base
validates :follower_id, :followed_id, presence: {message: 'Need an eligible follower and followee id'}
validates :followed_id, uniqueness: { scope: :follower_id}
belongs_to(
:follower,
class_name: "User"
)
belongs_to(
:followed,
class_name: "User"
)
end
如果有任何方法可以做到这一点并不需要大量的代码,我真的很想知道。提前谢谢。
答案 0 :(得分:0)
我不确定您的确切用例,但我对人们可以互相关注的系统的看法,似乎阻止者始终是被关注的人。如果是这种情况,那么这是一个实现:
def destroy_blocked_relationships
Relationship.where(follower_id:blocked_user_id, followed_id:blocker_id).destroy_all
true
end
如果阻止某人被人关注是有道理的,你可以加上:
Relationship.where(follower_id:blocker_id, followed_id:blocked_user_id).destory_all
这里一共都是,如果没有关系,就停止保存Block:
before_save :destroy_blocked_relationships
def destroy_blocked_relationships
relationships = Relationship.where("(follower_id = ? AND followed_id = ?) OR (followed_id = ? AND follower_id = ? )", blocked_user_id, blocker_id, blocked_user_id, blocker_id)
relationships.destroy_all
relationships.present? # Omit this line if the save should continue regardless
end
答案 1 :(得分:0)
这是我的理解:
考虑制作两个模型,BlockedPost和BlockedUser。然后,制作两个#make
方法。这使得所有相关逻辑更容易推理。
# class BlockedPost
def make(user, post)
transaction do
create!(user: user, post: post)
BlockedUser.make(user, post.author)
end
end
# class BlockedUser
def make(user, blocked_user)
transaction do
create!(user: user, blocked_user: blocked_user)
Relationship.where(follower: user, following: blocked_user).destroy_all
Relationship.where(follower: blocked_user, following: user).destroy_all
end
end