【问题标题】:Rails 5.1 - ActionCable not updating?Rails 5.1 - ActionCable 没有更新?
【发布时间】:2018-06-03 21:48:48
【问题描述】:

当我尝试使用 ActionCable 发表评论时,一切正常,但是,我总是必须刷新页面才能看到评论本身被渲染。有什么想法有什么问题吗?尝试重新启动服务器、注销、登录等。但没有任何帮助。

blogs.coffee

jQuery(document).on 'turbolinks:load', ->
  comments = $('#comments')
  if comments.length > 0
    App.global_chat = App.cable.subscriptions.create {
      channel: "BlogsChannel"
      blog_id: comments.data('blog-id')
    },
    connected: ->
    disconnected: ->
    recieved: (data) ->
      comments.append data['comment']
    send_comment: (comment, blog_id) ->
      @perform 'send_comment', comment: comment, blog_id: blog_id
  $('#new_comment').submit (e) ->
    $this = $(this)
    textarea = $this.find('#comment_content')
    if $.trim(textarea.val()).length > 1
      App.global_chat.send_comment textarea.val(),
      comments.data('blog-id')
      textarea.val('')
    e.preventDefault()
    return false

Blogs_channel.rb

class BlogsChannel < ApplicationCable::Channel
  def subscribed
    stream_from "blogs_#{params['blog_id']}_channel"
  end

  def unsubscribed
  end

  def send_comment(data)
    current_user.comments.create!(content: data['comment'], blog_id: data['blog_id'])
  end
end

评论.rb

class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :blog

  validates :content, presence: true, length: { minimum: 1, maximimum: 1000 }

  after_create_commit { CommentBroadcastJob.perform_later(self) }
end

CommentBroadcastJob.rb

class CommentBroadcastJob < ApplicationJob
  queue_as :default

  def perform(comment)
    ActionCable.server.broadcast "blogs_#{comment.blog.id}_channel", comment: render_comment(comment)
  end


  private

  def render_comment(comment)
    CommentsController.render partial: 'comments/comment', locals: { comment: comment }
  end
end

_comment.html.erb

<div class="comment-card">

  <div class="card">
    <div class="card-block">
      <div class="row">
        <div class="col-md-1">

        </div>

        <div class="col-md-11">
          <%= comment.content %>
        </div>
      </div>
    </div>
  </div>
</div>

评论在 show.html.erb 页面中呈现:

<%= render 'comments/comment_form' %>



<div id="comments" data-blog-id="<%= @blog.id %>">
  <%= render @blog.comments %>
</div>

提交新评论时的控制台日志:

[ActionCable] [test1@test.com] [1] Finished "/cable/" [WebSocket] for 127.0.0.1 at 2017-12-21 09:42:47 +0100
[ActionCable] [test1@test.com] [1] BlogsChannel stopped streaming from blogs_3_channel
Started GET "/cable" for 127.0.0.1 at 2017-12-21 09:42:48 +0100
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2017-12-21 09:42:48 +0100
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 1], ["LIMIT", 1]]
[ActionCable] [test1@test.com] [1] Registered connection (Z2lkOi8vdWRlbXktdHV0b3JpYWwtcmFpbHMvVXNlci8x)
[ActionCable] [test1@test.com] [1] BlogsChannel is transmitting the subscription confirmation
[ActionCable] [test1@test.com] [1] BlogsChannel is streaming from blogs_3_channel

chrome 控制台内没有错误或任何错误。

有什么想法吗?在 route.rb 内部我使用mount ActionCable.server =&gt; '/cable',如果这可能有帮助的话。似乎它没有被激活/使用,不知道为什么。

提前致谢!

编辑:

在某些时候,我在终端日志中收到以下错误:

[ActiveJob] [CommentBroadcastJob] [b32437ee-cf29-4323-97e9-841c87300518] Error performing CommentBroadcastJob (Job ID: b32437ee-cf29-4323-97e9-841c87300518) from Async(default) in 82.51ms: ActionView::Template::Error (undefined local variable or method `comment' for #<#<Class:0x00007f9b948bbed8>:0x00007f9b93a8fb98>
Did you mean?  ��comment):

在def perform下运行byebug,结果:

[2, 11] in 
/app/jobs/comment_broadcast_job.rb
    2: class CommentBroadcastJob < ApplicationJob
    3:   queue_as :default
    4: 
    5:   def perform(comment)
    6:     byebug
=>  7:     ActionCable.server.broadcast "blogs_#{comment.blog.id}_channel", comment: render_comment(comment)
    8:   end

好吧,为什么评论未定义?同样,如果我刷新页面,即使出现此错误,我也会看到评论被渲染。

【问题讨论】:

  • 你在哪里打电话CommentBroadcastJob?从上面的代码中,没有任何调用它的痕迹。此外(我不再确定这一点),但在此之前/现在,您应该只将像 String 或 Integer 这样的原语作为参数传递给perform(因为它是由 Sidekiq 或 DelayedJob 序列化的),所以你可能会想要def perform(comment_id) \n comment = Comment.find(comment_id)
  • CommentBroadCast 由 Comment.rb 调用 after_create_commit { CommentBroadcastJob.perform_later(self) } 如果我在这里没有错(在 OP 中添加了文件)。我会用comment_id查看你的建议。
  • 尝试传递 id 而不是 object 本身:CommentBroadcastJob.perform_later(self.id) 但您还需要更新您的工作(请参阅我之前的评论)
  • 因为评论已创建(正如您所说,它在重新加载页面后显示),所以即使在您的 after_create_commit 之前,一切都可以正常工作。然后,调试的第一步是是否正在处理后台作业。那么你能在ActionCable.server.broadcast "blogs_#{comment.blog.id}_channel", comment: render_comment(comment)上方插入byebug吗?如果你还没有使用 byebug,这将暂停服务器/sidekiq/delayed_job,以便你可以检查东西。如果它没有暂停,那么这意味着作业没有被运行,
  • 感谢您的建议。我在 ActionCable.server.broadcast 部分上方插入了 byebug。我已经在 OP 中发布了结果。

标签: ruby-on-rails websocket coffeescript ruby-on-rails-5 actioncable


【解决方案1】:

所以我已经从原始文件(它来自课程)复制了 BroadCastJob.rb 文件,它终于可以工作了。我在我的文件与讲师文件中找不到任何错字。如果有人能找到它,请告诉我。

我的 CommentBroadcastJob.rb 文件:

class CommentBroadcastJob < ApplicationJob
  queue_as :default

  def perform(comment)
    ActionCable.server.broadcast "blogs_#{comment.blog.id}_channel", comment: render_comment(comment)
  end


  private

  def render_comment(comment)
    CommentsController.render partial: 'comments/comment', locals: { comment: comment }
  end
end

导师一:

class CommentBroadcastJob < ApplicationJob
  queue_as :default

  def perform(comment)
    ActionCable.server.broadcast "blogs_#{comment.blog.id}_channel", comment: render_comment(comment)
  end

  private

  def render_comment(comment)
    CommentsController.render partial: 'comments/comment', locals: { comment: comment }
  end
end

这是有效的。每当我删除这个并使用我的一个时,我都会遇到与以前相同的错误。当我使用讲师时,它最终会在发送消息后呈现消息。不知道差异应该在哪里。

【讨论】:

  • 看到这个问题已经有2年多了,我猜这不再是问题了;但是,我将您的代码放入测试文件并提交到 GitHub,然后将文件中的代码替换为讲师的代码并检查差异。您在此处发布的两个代码之间的唯一区别是 private 声明之前的额外行。这不应该影响一切的运行方式。所以,我不确定为什么简单地替换代码就可以了。您确定没有更改其他代码吗?您是否正在使用某种可以提供帮助的代码版本跟踪器?
猜你喜欢
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
  • 2018-06-13
  • 2016-07-08
  • 1970-01-01
  • 2018-02-16
  • 1970-01-01
相关资源
最近更新 更多