新手问题 写关注功能结果出现一个问题

msl12 · 2016年04月16日 · 最后由 msl12 回复于 2016年04月19日 · 2282 次阅读

最近学习 Ruby-China 的源码,我的关注代码大概由以下代码实现:

User Model 里面的代码:
def follow_user(user)
    return false if user.blank?
    self.transaction do
      self.push(following_ids: user.id)
      user.push(follower_ids: self.id)
    end
    #Notification.notify_follow(user.id, self.id)
  end
User 控制器里面的代码:
def follow
        current_user.follow_user(@user)
        redirect_to :back
    end
push 和 pull 方法的定义:
def push(hash)
    hash.each_key do |key|
      old_val=self[key] || []
      old_val<<hash[key].to_i
      old_val.uniq!
      update_attributes(key=>old_val)
    end
  end

  def pull(hash)
    hash.each_key do |key|
      old_val=self[key]
      return true if old_val.blank?
      old_val.delete(hash[key].to_i)
      update_attributes(key=>old_val)
    end
  end

结果发现..

self.transaction do
     self.push(following_ids: user.id)
     user.push(follower_ids: self.id)
   end

这里的事务处理关注动作时在我的数据库只能更新 following_ids 而并没有把被关注者的 follower_ids 给新增数据

例如:

<..following_ids: [1], follower_ids: []> # 这是关注者的一个刚刚执行'关注'后的'following_ids'值,可以看出被更新了
---------------------------------------------------------
<..following_ids: [], follower_ids: []> # 这是被关注者的一个刚刚执行'关注'后的'follower_ids'值,并没有被更新

为什么事务处理并没有把这两个数据同时改动呢?

log 文件里好像也是表示没有更新到 follower_ids

Started POST "/test/follow" for 127.0.0.1 at 2016-04-16 17:05:15 +0800
Processing by UsersController#follow as HTML
  Parameters: {"id"=>"test"}
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 9]]
   (0.1ms)  BEGIN
  User Exists (0.4ms)  SELECT  1 AS one FROM "users" WHERE ("users"."name" = 'msl' AND "users"."id" != 9) LIMIT 1
  SQL (0.4ms)  UPDATE "users" SET "following_ids" = $1, "updated_at" = $2 WHERE "users"."id" = $3  [["following_ids", "{1,6}"], ["updated_at", "2016-04-16 09:05:15.507663"], ["id", 9]]
  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE ("users"."name" = 'test' AND "users"."id" != 6) LIMIT 1
   (16.7ms)  COMMIT
Redirected to http://localhost:3000/test
Completed 302 Found in 37ms (ActiveRecord: 18.5ms)

不要学那个,历史原因那样的,关系数据库,本来不应该那样的

#2 楼 @huacnlee 蛤?什么意思..

#2 楼 @huacnlee 你是说那个事务处理不要那样写吗

Ruby-China 过去一直使用 MongoDB,前阵子才迁移到 PG,这里应该是兼容过去的设计才这样做的,是在模拟 Mongoid 的多对多关联的实现方式

而关注用户这事,就是用户间的多对多关联嘛,认清本质后去看看 ActiveRecord 多对多关联 的文档就行了

#6 楼 @jasl 原来如此啊,那我修改一下

我到觉得 postgres 的 array 类型 字段 做这个场景很酷啊

#11 楼 @huacnlee 谢谢,我看看

需要 登录 后方可回复, 如果你还没有账号请 注册新账号