ruby-on-railsajaxfayeprivate-pub

Rails create action Ajax returns Template Missing or Unknown Fomat


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 %>
    &nbsp;&nbsp;
    <%= 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"


Solution

  • 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