When i try to post an comment with ActionCable, everything works, however, i always have to refresh the page to see the comment itself get rendered. Any ideas whats wrong? Tried to restart the server, logout, login etc. But nothing really helped.
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
Comment.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>
The comment gets rendered inside the show.html.erb page with:
<%= render 'comments/comment_form' %>
<div id="comments" data-blog-id="<%= @blog.id %>">
<%= render @blog.comments %>
</div>
Console log when submitting a new comment:
[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
No errors inside chrome console or whatsoever.
Any ideas? Inside route.rb i use mount ActionCable.server => '/cable'
if this might help. It seems like it doesn't get activated / used, by no idea why.
Thanks in advance!
Edit:
At some point, i get the following error inside the terminal log:
[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):
Ran byebug under def perform, result:
[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
Well, why is comment undefined? Again, if i refresh the page, even with this error, i see the comment get rendered.