所以我有一个用户/用户配置文件的应用程序。目前,用户可以查看其他个人资料,发送消息和喜爱的用户个人资料。我还想添加该功能,以允许用户“隐藏用户”配置文件,以便他们不会再在搜索中看到用户,或任何其他内容。并在“设置”中提供选项以“隐藏”用户。
我怎么能这样做?我不清楚这个功能从哪里开始。
(如果您需要任何代码示例,模型,控制器请询问,我很乐意提供)
亲切的问候, 桑尼
答案 0 :(得分:0)
我相信一种方法是通过has_many创建一个many_to_many关系:通过用户和隐藏用户之间的关联。同样,用户和隐藏者(即隐藏用户的用户)之间存在另一种多对多的关系。最后,您应该能够做到这样的事情:
some_user.hidden_users
和some_user.hiders
(即隐藏某些用户的所有用户)。你可能大部分时间都不需要第二个。
所以要做的第一件事就是创建一个名为hiders_hidden_users(或任何你想要的)的连接表,它只包含两个字段:hider_id
和hidden_user_id
。
请注意,实际上,这些ID都会引用用户记录。您的HidersHiddenUser模型将如下所示:
class HidersHiddenUsers < ActiveRecord::Base
belongs_to :hidden_user, class_name: "User", foreign_key: "hidden_user_id"
belongs_to :hider, class_name: "User", foreign_key: "hider_id"
end
然后,您需要在User类中设置关系:
class User < ActiveRecord::Base
has_many :hiders_join, class_name: "HidersHiddenUser", foreign_key: "hider_id"
has_many :hidden_users_join, class_name: "HidersHiddenUser", foreign_key: "hidden_user_id"
has_many :hiders, through: :hiders_join
has_many :hidden_users, through: :hidden_users_join
end
请注意,在与连接表写入has_many关系时,必须指定类名和外键。请注意,您还必须使用相同的模型指定两次关系。
然后,说some_user想要隐藏user1和user2。您需要做的就是这样:
some_user.hidden_users << user1
some_user.hidden_users << user2
虽然我没有对此进行测试,但我相信它应该可行。
答案 1 :(得分:0)
可能有几种方法可以做到这一点,首先想到的方法是建立一个自我引用的多对多关系。
您需要创建连接表(我将其称为suppressed_users
)。我将展示rails模型,因为迁移除了外键之外没有任何东西。
class SuppressedUser < ActiveRecord::Base
belongs_to :user
belongs_to :suppressed_user, :class_name => "User", :foreign_key=>"suppressed_user_id"
end
在User
模型中,为了帮助干扰您的代码,您可以使用scope
轻松过滤此目标用户决定禁止(或隐藏)的所有用户:
class User < ActiveRecord::Base
has_many :suppressed_users // Optional
scope :without_hidden_users, -> (target_user) do
where.not("exists (?)",
SuppressedUser.select("1")
.where("users.id = suppressed_users.suppressed_user_id AND suppressed_users.user_id = ?", target_user))
end
end
关于范围的说明:我在这里做的是创建一个从属(或相关)子查询,在其中我检查目标用户是否已经抑制(或隐藏)我们的用户看着这一刻。换句话说,对users
结果集中的每一行(未经其他where
或join
条件过滤的那些行等)执行从属子查询。通过适当的索引,这不会对性能产生影响。
关于has_many :suppressed_users
的注意事项:从技术上讲,我所显示的查询不需要这样做,因此,如果它与您系统中的任何内容无关,则可以安全地将其删除
因此,如果我现在已登录,并且我想搜索符合某些条件的用户列表,那么在您的控制器中,您可以执行以下操作:
User.without_hidden_users(@current_user.id)...other conditions and such as needed
假设@current_user
代表当前登录的用户。