Мне удалось успешно настроить 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 вызывается с правильным идентификатором, но когда он переходит к захвату сообщения:
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, его нельзя найти в БД. Если я перезагружу страницу, сообщение, которое мы только что создали, работает. Не уверен, почему недавно транслируемое сообщение не находится в базе данных.
params[:id]
? Попробуйте использоватьparams.fetch(:id)
, чтобы убедиться, что ключ существует. Возможно, хэш состоит только из строковых ключей, а не из символов. - person Linus Oleander   schedule 30.01.2016find
вместоfind_by_id
? Кроме того, какую базу данных вы используете? - person Dani   schedule 04.02.2016