【问题标题】:HABTM mongoid following/followerHABTM mongoid 追随者/追随者
【发布时间】:2011-12-20 19:25:57
【问题描述】:

Mongoid 在 habtm 上附带了 .push,它设置了双向的 habtm 关系。尽管删除将#delete 关联记录,但没有记录的方法可以仅删除我见过的关系。有更好的方法吗?

有没有更好的方法来确保唯一性?

has_and_belongs_to_many :following, {class_name: 'User', inverse_of: :followers, inverse_class_name: 'User'}
  has_and_belongs_to_many :followers, {class_name: 'User', inverse_of: :following, inverse_class_name: 'User'}

  def follow!(user)
    self.following.push(user) # this pushes the inverse as well
    self.following_ids.uniq!
    self.save!
    user.follower_ids.uniq!
    user.save!
  end

  def unfollow!(user)
    self.following.delete(user.id)
    self.save!
    user.followers.delete(self.id)
    user.save!
  end

【问题讨论】:

    标签: ruby-on-rails mongoid has-and-belongs-to-many


    【解决方案1】:

    以下代码对我来说效果很好(mongoid 2.3.x):

    class User
      include Mongoid::Document
    
      field :name, type: String
    
      has_and_belongs_to_many :following, class_name: 'User', inverse_of: :followers, autosave: true
      has_and_belongs_to_many :followers, class_name: 'User', inverse_of: :following
    
      def follow!(user)
        if self.id != user.id && !self.following.include?(user)
          self.following << user
        end
      end
    
      def unfollow!(user)
        self.following.delete(user)
      end
    end
    

    没有inverse_class_name,没有保存调用,没有特殊处理,但排除了自我跟随。

    原因是,如果没有添加到关系语句中,mongoid 会自动使用dependent: nullify。使用autosave: true 可以保存关系更新(并且只需要关注,因为我们不直接更改关注者)。如果没有自动保存选项,您需要在方法中添加保存调用,因为 mongoid 不会自动保存关系更新(从 2.0.0.x 开始)。

    我把 if 子句作为块,所以你可以用异常处理来改变它 (else raise FooException)。

    .delete(user) 没问题,在 mongoid 文档中也提到过:http://mongoid.org/docs/relations/referenced/n-n.html(向下滚动到“DEPENDENT BEHAVIOUR”)。

    【讨论】:

    • 这里有一些很棒的东西。但是,我之前做了一些测试,落入了同样的陷阱(除非我弄错了): .delete(user) 从数据库中删除用户,而 nullify 指的是对现在删除的用户的任何引用跨度>
    • .delete 在 .following 散列上,而不是在用户对象本身上。就像医生说的“孤立一个孩子的关系”。它可以完成这项工作,我对其进行了测试,并且可以正常工作。
    • 代码!self.following.include?(user)在以下关系中没有太多用户时很酷,但如果你有10K用户......性能不是很好:/
    • @K'ao 那有什么办法呢?会独一无二!更快吗?也许最好的方法是优雅地处理重复——尽管创建 10k 条推文也不是最快的..
    • @PeterEhrlich:我们现在正在尝试使用最常用的原子持久性 (link)。看看#add_to_set,你的条件“包括?”就没有必要了。
    猜你喜欢
    • 2019-07-03
    • 1970-01-01
    • 2017-12-08
    • 2021-10-09
    • 2017-12-17
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 2018-07-12
    相关资源
    最近更新 更多