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.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% 存在しているにもかかわらず、DB から Post をフェッチできません。

壁にすでにいくつかの投稿がある場合、それらは正常に接続できます。投稿が作成され、ActionCable を介してブロードキャストされた場合にのみ、DB で見つけることができません。ページをリロードすると、作成したばかりの投稿が機能します。新しくブロードキャストされた投稿がデータベースで見つからない理由がわからない

4

1 に答える 1

0

コントローラーで両方のブロードキャストを設定しましたか?

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

それ以外の場合は、両方からストリーミングできます

"Wall(#{profile.id})"

データを受け取った後にロジックを追加します。

于 2016-11-01T20:41:10.447 に答える