Rails 5: ActionCable 和数据库不同步

6

我成功地设置了ActionCable,监听频道,验证请求等。但是,当我尝试在创建后立即连接到频道时,遇到了一个奇怪的错误(很难解释,请参见下文)。

我的设置如下:一个个人资料有一个墙壁,这个墙壁包含许多帖子。每个帖子都有自己的频道,而墙壁本身也有自己的频道。当在墙上创建帖子时,它通过ActionCable进行更新:

# Wall's Cable Channel
class WallsChannel < ApplicationCable::Channel
  def subscribed
    profile = Profile.find_by_id params[:id]

    if ability.can? :subscribe, profile
      stream_from "Wall(#{profile.id})"
    else
      reject
    end
  end
end

# Broadcasting to the wall
ActionCable.server.broadcast 'Wall(:id:)', { :data: }

# Client Side
GlobalCable.cable.subscriptions.create({channel: 'WallsChannel', id :id: }, {
    received: function(data) {
        // do stuff with a new post on a wall
    }
});

我简化了它,但它可以按预期工作。当创建新帖子时,会触发墙面频道,客户端接收帖子并一切正常。
问题是连接广播的新帖子。当我去听取新帖子时,无法从数据库获取帖子。
# Posts Cable Channel
class PostsChannel < ApplicationCable::Channel
  def subscribed
    post = Post.find_by_id params[:id]

    if ability.can? :subscribe, post
      stream_from "Post({#{post.id}})"
    else
      reject
    end
  end
end

# Client side
GlobalCable.cable.subscriptions.create({ channel: 'PostsChannel', id: id }, {
    received: function(data) {
        // do stuff
    }
});

具体而言,订阅了PostsChannel的方法将以适当的id被调用,但是当它去获取post时:
post = Post.find_by_id params[:id]
# SQL that is generated 
# SELECT  `posts`.* FROM `posts` WHERE `posts`.`id` = :id: LIMIT 1
# ^ Always returns null even though we just created the post

无论发生什么情况,它始终返回null。换句话说,即使它100%存在,它也未能从数据库中获取Post。

如果墙上已经有几篇文章,它们可以成功连接。仅当通过ActionCable创建并广播文章时,它才无法在DB中找到。如果重新加载页面,则刚刚创建的文章有效。不确定为什么新广播的文章不能在db中找到。


你确定 params[:id] 已经设置了吗?尝试使用 params.fetch(:id) 来确保该键存在。可能哈希表只包含字符串键而不是符号键。 - Linus Oleander
params[:id] 100% 存在 - user3023421
你从客户端传递的ID是从哪里获取的?这个ID是从页面的id还是data属性中获取的? - cll
只是出于好奇 - 你尝试过使用 find 而不是 find_by_id 吗?另外 - 你正在使用哪个数据库? - Dani
@Dani 使用 find 也不行,我正在使用 mySQL。当我运行 Post.order(id: :desc).limit(1) 时,它不会返回新创建的 post,而是返回它之前的 post。 - user3023421
显示剩余2条评论
1个回答

0

你在控制器中设置了两个广播吗?

ActionCable.server.broadcast 'Post(:id:)', { :data: }

否则,您可以从两个位置同时流式传输。
"Wall(#{profile.id})"

在接收数据后添加逻辑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接