I'm trying to implement private_pub on a one-to-one chat app, without private_pub everything works fine just not ideal chat app since no websocket is used for autoupdates. I tried implementing as on RailsCasts of private_pub but i am getting either template missing or unknown format. Here is my code:
Routes
resources :conversations do
resources :messages
end
I have a button in my user show page to start a chat(which creates/uses a conversation and shows up a conversation show page like a one to one chat box on facebook/gchat , a conversation has many messages):
<% unless current_user == @user %>
<%= link_to "Send Message", conversations_path(:sender_id => current_user.id , :recipient_id => @user.id ), :method => :post, class: "btn btn-success btn-xs start-conversation" %>
<% end %>
Conversation Controller
class ConversationsController < ApplicationController
before_filter :authenticate_user!
layout false
def create
if Conversation.between(params[:sender_id],params[:recipient_id]).present?
@conversation = Conversation.between(params[:sender_id],params[:recipient_id]).first
else
@conversation = Conversation.create!(conversation_params)
end
@conversation.save!
redirect_to @conversation
end
def show
@conversation = Conversation.find(params[:id])
@reciever = interlocutor(@conversation)
@messages = @conversation.messages
@message = Message.new
end
private
def conversation_params
params.permit(:sender_id, :recipient_id)
end
def interlocutor(conversation)
current_user == conversation.recipient ? conversation.sender : conversation.recipient
end
end
Convesation Show View
<% content_for :bottom do %>
<%= subscribe_to conversation_path(@conversation) %>
<% end %>
<div class="chatboxhead">
<div class="chatboxtitle">
<i class="fa fa-comments"></i>
<h1><%= @reciever.username %> </h1>
</div>
<div class="chatboxoptions">
<%= link_to "<i class='fa fa-minus'></i> ".html_safe, "#", class: "toggleChatBox", "data-cid" => @conversation.id %>
<%= link_to "<i class='fa fa-times'></i> ".html_safe, "#", class: "closeChat", "data-cid" => @conversation.id %>
</div>
<br clear="all"/>
</div>
<div class="chatboxcontent">
<% if @messages.any? %>
<%= render @messages.reverse %>
<% end %>
</div>
<div class="chatboxinput">
<%= form_for([@conversation, @message], :remote => true) do |f| %>
<%= f.text_area :body, class: "chatboxtextarea", "data-cid" => @conversation.id %>
<%= f.submit " Send", class: "btn btn-primary btn-xs"%>
<% end %>
</div>
Message Controller
class MessagesController < ApplicationController
before_filter :authenticate_user!
skip_before_filter :verify_authenticity_token, only: [:create]
def create
@conversation = Conversation.find(params[:conversation_id])
@message = @conversation.messages.build(message_params)
@message.user_id = current_user.id
@message.save!
@path = conversation_path(@conversation)
end
private
def message_params
params.require(:message).permit(:body)
end
end
Message's message partial
#_message.html.erb
<li class="<%= self_or_other(message) %>">
<div class="avatar">
<img src="http://placehold.it/50x50" />
</div>
<div class="chatboxmessagecontent">
<p><%= message.body %></p>
<time datetime="<%= message.created_at %>" title="<%= message.created_at.strftime("%d %b %Y at %I:%M%p") %>">
<%= message_interlocutor(message).username %> <%= message.created_at.strftime("%H:%M %p") %>
</time>
</div>
</li>
Message's create view
#create.js.erb
<% publish_to @path do %>
var id = "<%= @conversation.id %>";
var chatbox = $(".chatboxcontent");
var sender_id = "<%= @message.user.id %>";
var reciever_id = $('meta[name=user-id]').attr("content");
chatbox.append("<%= j render( partial: @message ) %>");
chatbox.scrollTop(chatbox[0].scrollHeight);
if (sender_id != reciever_id) {
chatBox.chatWith(id);
chatbox.children().last().removeClass("self").addClass("other");
chatbox.scrollTop(chatbox[0].scrollHeight);
chatBox.notify();
}
<% end %>
On Message Controller, create action the above code results "Missing Template" and if I put a respond_to as:
respond_to do |format|
format.js { render 'create.js.erb' }
end
it results "Unknown Format"
This error occurs when you have not added jquery_ujs
file. You only included the jquery file.
So you need to add both files manually in you view or require them in application.js
or any other file which you are using for specific layout.
Depending upon your scenario, you can follow 1st or 2nd solution.
1st solution:
<%= javascript_include_tag :jquery, :jquery_ujs %>
on your conversation show page.
2nd solution:
remove the "layout false"
on your conversation controller