将Actioncable与Rails集成时出错

时间:2018-06-25 23:37:53

标签: javascript ruby-on-rails ruby-on-rails-5 actioncable rails-activejob

我正在尝试建立一个群组聊天系统,该群组的成员可以在群组的聊天部分中留下评论。我正在将Actioncable与Rails 5一起实时实现,但无法克服特定的障碍。聊天评论照常发布到数据库,但是渲染和实时功能在某些地方出错。以下是所有关联的代码示例以及来自我的终端的错误。我已经为此工作了很长时间。我非常需要启发。

错误: (整个错误消息很长,但这是错误开始的地方。)

Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-06-25 18:11:13 -0500
GroupChatCommentsChannel stopped streaming from group:5:group_chat_comments
Started GET "/cable" for 127.0.0.1 at 2018-06-25 18:11:13 -0500
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-06-25 18:11:13 -0500
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
GroupChatCommentsChannel is transmitting the subscription confirmation
GroupChatCommentsChannel#follow({"group_id"=>5})
GroupChatCommentsChannel is streaming from group:5:group_chat_comments
Started POST "/groups/5/group_chat_comments" for 127.0.0.1 at 2018-06-25 18:11:50 -0500
Processing by GroupChatCommentsController#create as JS
  Parameters: {"utf8"=>"✓", "group_chat_comment"=>{"body"=>"2"}, "commit"=>"Comment", "group_id"=>"5"}
  Group Load (0.4ms)  SELECT  `groups`.* FROM `groups` WHERE `groups`.`id` = 5 LIMIT 1
  User Load (0.2ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
   (0.2ms)  BEGIN
  Group Load (0.3ms)  SELECT  `groups`.* FROM `groups` WHERE `groups`.`id` = 5 LIMIT 1
  SQL (5.8ms)  INSERT INTO `group_chat_comments` (`body`, `user_id`, `group_id`, `created_at`, `updated_at`) VALUES ('2', 1, 5, '2018-06-25 23:11:50', '2018-06-25 23:11:50')
   (7.2ms)  COMMIT
[ActiveJob] Enqueued RenderGroupChatCommentJob (Job ID: ddceb77d-7c5c-42a3-8570-55d09a569c9e) to Async(default) with arguments: #<GlobalID:0x007f87af0ff7d8 @uri=#<URI::GID gid://news/GroupChatComment/4>>
  Rendering group_chat_comments/create.js.erb
  Rendered group_chat_comments/_new.html.erb (1.8ms)
  Rendered group_chat_comments/create.js.erb (31.6ms)
Completed 200 OK in 201ms (Views: 75.1ms | ActiveRecord: 36.5ms)


  GroupChatComment Load (0.2ms)  SELECT  `group_chat_comments`.* FROM `group_chat_comments` WHERE `group_chat_comments`.`id` = 4 LIMIT 1
[ActiveJob] [RenderGroupChatCommentJob] [ddceb77d-7c5c-42a3-8570-55d09a569c9e] Performing RenderGroupChatCommentJob (Job ID: ddceb77d-7c5c-42a3-8570-55d09a569c9e) from Async(default) with arguments: #<GlobalID:0x007f87ab6a1960 @uri=#<URI::GID gid://news/GroupChatComment/4>>
[ActiveJob] [RenderGroupChatCommentJob] [ddceb77d-7c5c-42a3-8570-55d09a569c9e]   Rendered group_chat_comments/_group_chat_comment.html.erb (26.1ms)
[ActiveJob] [RenderGroupChatCommentJob] [ddceb77d-7c5c-42a3-8570-55d09a569c9e] Error performing RenderGroupChatCommentJob (Job ID: ddceb77d-7c5c-42a3-8570-55d09a569c9e) from Async(default) in 60.85ms: ActionView::Template::Error (No route matches {:action=>"show", :controller=>"group_chat_comments", :group_id=>nil, :id=>"4"}, missing required keys: [:group_id]):

代码:

路线:

  resources :groups do
    resources :group_chat_comments
  end

  mount ActionCable.server => '/cable'

型号:

class GroupChatComment < ApplicationRecord
  belongs_to :user
  belongs_to :group

  after_create_commit { RenderGroupChatCommentJob.perform_later self }
end

控制器:

class GroupChatCommentsController < ApplicationController
  before_action :set_group
  before_action :authenticate_user!

  def create
    @group_chat_comment = GroupChatComment.create! body: params[:group_chat_comment][:body], group_id: @group.id, user: current_user
  end

  def destroy
    @group_chat_comment = GroupChatComment.find(params[:id])

    @group_chat_comment.destroy
      redirect_to @group
  end

  private

  def set_group
    @group = Group.find(params[:group_id])
  end
end

工作:

class RenderGroupChatCommentJob < ApplicationJob
  queue_as :default

  def perform(group_chat_comment)
    ActionCable.server.broadcast "group:#{group_chat_comment.group_id}:group_chat_comments", foo: render_group_chat_comment(group_chat_comment)
  end

  private
    def render_group_chat_comment(group_chat_comment)
      ApplicationController.renderer.render(partial: 'group_chat_comments/group_chat_comment', locals: { group_chat_comment: group_chat_comment })
    end
end

频道:

class GroupChatCommentsChannel < ApplicationCable::Channel
  def follow(params)
    stop_all_streams
    stream_from "group:#{params['group_id'].to_i}:group_chat_comments"
  end

  def unfollow
    stop_all_streams
  end
end

Channel CoffeeScript:

App.group_chat_comments = App.cable.subscriptions.create "GroupChatCommentsChannel",
  collection: -> $('#group_chat_comments')

  connected: ->
    setTimeout =>
      @followCurrentGroup()
    , 1000

  disconnected: ->

  followCurrentGroup: ->
    groupId = @collection().data('group-id')
    if groupId
      @perform 'follow', group_id: groupId
    else
      @perform 'unfollow'

  received: (data) ->
    @collection().append(data['group_chat_comment'])

Cable.js:

//= require action_cable
//= require_self
//= require_tree ./channels

(function() {
  this.App || (this.App = {});
  App.cable = ActionCable.createConsumer();
}).call(this);

视图:

Create.js:

$('#new_group_chat_comment').replaceWith('<%=j render 'group_chat_comments/new', group: @group %>');

_group_chat_comment部分:

<% cache group_chat_comment do %>
  <div class="group_chat_comment">
    <p>
      <%= group_chat_comment.body %>
      <%= link_to 'Delete', group_group_chat_comment_path(@group, group_chat_comment), method: :delete %>
    </p>
  </div>
<% end %>

_group_chat_comments部分:

<%= render 'group_chat_comments/new', group: @group %>

<section id="group_chat_comments" data-group-id="<%= @group.id %>">
  <%= render @group.group_chat_comments %>
</section>

_new部分:

<%= form_for [ @group, GroupChatComment.new ], remote: true do |f| %>
  <div class="group-comment">
    <%= f.text_area :body %>
  </div>
    <br>
  <div class="group-comment-submit">
    <%= f.submit 'Comment' %>
  </div>
<% end %>

0 个答案:

没有答案