我能够成功设置 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.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% 存在,它也无法从数据库中获取帖子。
如果我在墙上已经有一些帖子,他们就可以成功连接。仅当通过 ActionCable 创建和广播帖子时,才能在数据库中找到它。如果我重新加载页面,我们刚刚创建的帖子就会起作用。不知道为什么在数据库中找不到新广播的帖子