javascript - 将 Actioncable 与 Rails 集成时出错
问题描述
我正在尝试建立一个群聊系统,群组成员可以在群组的聊天部分留下评论。我正在使用带有 Rails 5 的 Actioncable 来实时实现这一点,但我无法克服一个特定的障碍。聊天评论照常发布到数据库中,但渲染和实时功能出现错误。以下是所有附属代码示例和来自我的终端的错误。我已经为此工作了很多年。我迫切需要启蒙。
错误:( 整个错误消息很长,但这是错误开始的地方。)
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
频道 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'])
电缆.js:
//= require action_cable
//= require_self
//= require_tree ./channels
(function() {
this.App || (this.App = {});
App.cable = ActionCable.createConsumer();
}).call(this);
观点:
创建.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>
_新部分:
<%= 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 %>
解决方案
推荐阅读
- ruby-on-rails - Rails 设计:configure_permitted_parameters 未按预期工作
- spring-boot - 403 禁止在访问 Okta Userinfo 端点时使用 Springboot
- rust - 将 mut 引用传递给函数,然后将其取回
- css - Google Maps API 响应式搜索框
- polymorphism - 如果我在一个类中有 Object equals(Object other) 和 equals (C other),接下来的调用中将使用哪个方法:
- python - 如何使用 matplot 绘制动画多维列表?
- c++ - 如何检测鼠标光标在窗口之外?
- python - 插入列熊猫中的重复值
- c++ - 无法在 VScode“未定义参考”C++ 中包含 .H 文件
- java - 在更新和删除方法中显示 toast 消息的问题