【问题标题】:Rails 5 Actioncable not showing new recordsRails 5 Actioncable 未显示新记录
【发布时间】:2017-11-18 14:15:25
【问题描述】:

我试图让动作电缆工作。所以我创建了一个带有属性名称的模型 Division 的简单应用程序。

index.html.erb

  <div class="container">

<p id="notice"><%= notice %></p>
<% content_for(:page_header) {"DIVISIONS"} %>

<table class="table table-striped">

  <thead >
    <tr>
      <th>Name</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <div id='divisions'>
    <%= render @divisions %>
  </div>
  </tbody>

</div>
<br>

<%= link_to 'New Division', new_division_path %>
</div>

_division.html.erb 部分

    <tr>
  <td><%= division.name %></td>
  <td><%= link_to 'Show', division %></td>
  <td><%= link_to 'Edit', edit_division_path(division) %></td>
  <td><%= link_to 'Destroy', division, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>

app/assets/javascripts/channels/division.coffee

    App.division= App.cable.subscriptions.create "DivisionChannel",
  connected: ->


  disconnected: ->


  received: (data) ->

    $("#divisions").append(data["division"])

  create: (division) ->

    @perform 'create', division: division

app/channels/division_channel.rb

class DivisionChannel < ApplicationCable::Channel

    def subscribed
      stream_from "divisions_channel"
    end

    def unsubscribed
      # Any cleanup needed when channel is unsubscribed
    end

    def create(data)
      # data is like parameters received from front end
      Division.create({ name: data['name'] })
    end
  end

divisions_controller

  class DivisionsController < ApplicationController
      def index
        @divisions = Division.all
      end

      def new
        @division = Division.new
      end



          def create
       division = Division.new(division_params)
       if division.save
         ActionCable.server.broadcast 'divisions',
           division: division.name
         head :ok
       end
     end

      def edit
        @division = Division.find_by_id(params[:id])
      end

      def update
        @division = Division.find_by_id(params[:id])

          respond_to do |format|
            if @division.update(division_params)
              format.html { redirect_to @division, notice: 'Division was successfully updated.' }
              format.json { render :show, status: :ok, location: @division }
            else
              format.html { render :edit }
              format.json { render json: @division.errors, status: :unprocessable_entity }
            end
          end
        end


      def delete
      end

      def destroy
        @division.destroy
        respond_to do |format|
          format.html { redirect_to divisions_url, notice: 'Division was successfully destroyed.' }
          format.json { head :no_content }
        end
      end

      def show
          @division = Division.find_by_id(params[:id])
      end

      def division_params
          params.require(:division).permit(:name)
        end
    end

师.rb

class Division < ApplicationRecord
  after_create_commit do
    DivisionCreationEventBroadcastJob.perform_later(self)
  end
end

app/jobs/division_creation_event_broadcast_job_job.rb

class DivisionCreationEventBroadcastJob < ApplicationJob
  queue_as :default

  def perform(division)

    ActionCable.server.broadcast 'divisions_channel', division: render_division(division)

  end

  private

  def render_division(division)

    ApplicationController.render(partial: 'divisions/division', locals: { division: division})
  end
end

当我创建一个新的部门并重定向到http://localhost:3000/divisions时,屏幕是空白的,记录被保存但没有在其他浏览器上广播。

这是我在终端上得到的:

Started POST "/divisions" for 127.0.0.1 at 2017-11-18 22:08:50 +0800
Processing by DivisionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"+JjDpuJXIlnJc+yZXVJbBx9JeYA1X1owW5bOH4x6hTiddEWLst6F/fup7r1Kz0L4+6CKDsp9C0NorNVxzuh9gQ==", "division"=>{"name"=>"dgfhfdg"}, "commit"=>"Create Division"}
   (0.3ms)  BEGIN
  SQL (0.3ms)  INSERT INTO `divisions` (`name`, `created_at`, `updated_at`) VALUES ('dgfhfdg', '2017-11-18 14:08:50', '2017-11-18 14:08:50')
   (0.6ms)  COMMIT
[ActiveJob] Enqueued DivisionCreationEventBroadcastJob (Job ID: a3e4564d-6743-44da-9d48-dbb114812a67) to Async(default) with arguments: #<GlobalID:0x007f02f80c1708 @uri=#<URI::GID gid://bcz/Division/61>>
[ActionCable] Broadcasting to divisions: {:division=>"dgfhfdg"}
Completed 200 OK in 7ms (ActiveRecord: 1.2ms)


  Division Load (0.9ms)  SELECT  `divisions`.* FROM `divisions` WHERE `divisions`.`id` = 61 LIMIT 1
[ActiveJob] [DivisionCreationEventBroadcastJob] [a3e4564d-6743-44da-9d48-dbb114812a67] Performing DivisionCreationEventBroadcastJob (Job ID: a3e4564d-6743-44da-9d48-dbb114812a67) from Async(default) with arguments: #<GlobalID:0x007f02f809a7e8 @uri=#<URI::GID gid://bcz/Division/61>>
[ActiveJob] [DivisionCreationEventBroadcastJob] [a3e4564d-6743-44da-9d48-dbb114812a67]   Rendered divisions/_division.html.erb (0.9ms)
[ActiveJob] [DivisionCreationEventBroadcastJob] [a3e4564d-6743-44da-9d48-dbb114812a67] [ActionCable] Broadcasting to divisions_channel: {:division=>"<tr>\n  <td>dgfhfdg</td>\n  <td><a href=\"/divisions/61\">Show</a></td>\n  <td><a href=\"/divisions/61/edit\">Edit</a></td>\n  <td><a data-confirm=\"Are you sure?\" rel=\"nofollow\" data-method=\"delete\" href=\"/divisions/61\">Destroy</a></td>\n</tr>\n"}
[ActiveJob] [DivisionCreationEventBroadcastJob] [a3e4564d-6743-44da-9d48-dbb114812a67] Performed DivisionCreationEventBroadcastJob (Job ID: a3e4564d-6743-44da-9d48-dbb114812a67) from Async(default) in 6.06ms

我做错了什么?

【问题讨论】:

  • 您是否在DivisionCreationEventBroadcastJob 中设置了断点并调用了它?如果是,ActionCable.server.broadcast 'divisions_channel' 是否会在app/assets/javascripts/channels/division.coffee 内触发您前端的代码?您可以通过在 js 代码中设置断点来检查
  • 嗨,我尝试设置断点并且 DivisionCreationEventBroadcastJob 和 app/assets/javascripts/channels/division.coffee 都被调用。但我认为终端的输出也很清楚。在这一点上,我认为问题出在视图中。
  • 抱歉,实际上 app/assets/javascripts/channels/division.coffee 中的代码没有被调用,因为没有触发断点。
  • 我写了一个答案,你需要引用我来通知我@Catmal

标签: ruby-on-rails actioncable


【解决方案1】:

这是我发送消息时的服务器日志

Started POST "/messages" for 127.0.0.1 at 2017-11-19 20:35:09 +0100
Processing by MessagesController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"K3oc4eHMcihA38CNFSFifxHAQ7qsCqqwhxkAcf2+RoCfHL+vW6B4N1w4amHR+6Hy7TOQlOSEJ9A7KWsNNKTnnA==", "message"=>{"content"=>" asfdsfsd", "chatroom_id"=>"19"}, "commit"=>"send"}
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 14], ["LIMIT", 1]]
  Chatroom Load (0.3ms)  SELECT  "chatrooms".* FROM "chatrooms" WHERE "chatrooms"."id" = $1 LIMIT $2  [["id", 19], ["LIMIT", 1]]
   (0.1ms)  BEGIN
  SQL (0.5ms)  INSERT INTO "messages" ("content", "user_id", "created_at", "updated_at", "chatroom_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["content", " asfdsfsd"], ["user_id", 14], ["created_at", "2017-11-19 19:35:09.198584"], ["updated_at", "2017-11-19 19:35:09.198584"], ["chatroom_id", 19]]
   (21.7ms)  COMMIT
  Message Load (0.3ms)  SELECT  "messages".* FROM "messages" WHERE "messages"."chatroom_id" = $1 ORDER BY "messages"."id" DESC LIMIT $2  [["chatroom_id", 19], ["LIMIT", 2]]
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 14], ["LIMIT", 1]]
[ActionCable] Broadcasting to messages: {:message=>" asfdsfsd", :user=>"federico", :chatroom_id=>19, :lastuser=>"federico"}
MessagesChannel transmitting {"message"=>" asfdsfsd", "user"=>"federico", "chatroom_id"=>19, "lastuser"=>"federico"} 

不同之处在于您缺少这一行,这会触发app/assets/javascripts/channels/division.coffee 中的received 函数

MessagesChannel transmitting {"message"=>" asfdsfsd", "user"=>"federico", "chatroom_id"=>19, "lastuser"=>"federico"} 

这是我的日志的其余部分

Started GET "/cable" for 127.0.0.1 at 2017-11-19 20:28:27 +0100
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-19 20:28:28 +0100
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
MessagesChannel is transmitting the subscription confirmation
MessagesChannel is streaming from messages

主要是

  1. 我的服务器在启动时做的第一件事是向有线服务器发送GET '/cable' for 127.0.0.1 的获取请求,它正在连接到 websocket。这就是我在routes.rb 中包含的内容

    mount ActionCable.server => '/cable' 
    

    我也收到以下消息

    Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
    
  2. 然后我得到的信息是

    MessagesChannel is transmitting the subscription confirmation
    

    最重要的

    MessagesChannel is streaming from messages`
    

    它是streaming from messages,因为这是我设置Channel的方式,对你来说应该是:

    DivisionChannel is streaming from divisions_channel 
    

    如果用户离开则MessagesChannel stopped streaming from messages

您也可以进入Developer Toolbar 网络选项卡并选择电缆入口。从截图中你可以看到我选择了Cable并在右边我检查了Frames选项卡,我可以找到从服务器发送的以下命令

{"command":"subscribe", "identifier":"{\"channel\":\"MessagesChannel\"}"}

然后当我收到来自服务器的消息时,我的框架中有:

{"identifier":"{\"channel\":\"MessagesChannel\"}","message":{"message":"this is my test","user":"ezio","chatroom_id":19,"lastuser":"federico"}}

【讨论】:

  • 这里的问题是表单和索引(或显示重要的内容)位于不同的页面上。所以我在新视图上创建了一个部门,但后来我被重定向到索引。这对于可操作的使用毫无意义。我的意图是从一个具有索引、显示、新视图的基本应用程序开始,并使其成为实时的。但我忽略了一个基本步骤,即在同一视图上显示新记录,在本例中为索引。因此,在修复该问题后,我又回到了另一个问题中遇到的相同问题。这是使用表单(帖子)创建记录,并使用 actioncable 实时显示它们。
猜你喜欢
  • 1970-01-01
  • 2021-09-29
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 2018-09-26
  • 1970-01-01
相关资源
最近更新 更多