I'm following this tutorial to create a real-time chat in rails app: http://josephndungu.com/tutorials/gmail-like-chat-application-in-ruby-on-rails
Unlike this example, where you can click on a button that belongs to the user and the chat will pop up and it stays on the user index page(root), I would like to have an "embedded" chat, so when you go to the the user show page with and http request it will be already there and ready for the input.
How could I do that? At the moment if I try to embed the app says there is no conversation.id. I guess the reason is that the JS gets loaded after the site is rendered, so conversation.id is not there yet when it's needed. I tried to call the conversations controller's create action for the users controller, but I haven't been able to pull it off.
Here is the current code:
Button that initializes the conversation:
<%= link_to "Send message", "#", class: "btn btn-success btn-xs start-conversation", "data-sid" => current_user.id, "data-rip" => @user.id %>
users.js (sending data to create action to conversations controller)
$('.start-conversation').click(function (e) {
e.preventDefault();
var sender_id = $(this).data('sid');
var recipient_id = $(this).data('rip');
$.post("/conversations", { sender_id: sender_id, recipient_id: recipient_id }, function (data) {
chatBox.chatWith(data.conversation_id);
});
});
chat.js
chatBox = {
/**
* creates an inline chatbox on the page by calling the
* createChatBox function passing along the unique conversation_id
*
* @param conversation_id
*/
chatWith: function (conversation_id) {
chatBox.createChatBox(conversation_id);
$("#chatbox_" + conversation_id + " .chatboxtextarea").focus();
},
conversations controller
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
render json: { conversation_id: @conversation.id }
end
def show
@conversation = Conversation.find(params[:id])
@receiver = 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
show.html.erb (conversation window that pops up)
<div class="chatboxhead">
<div class="chatboxtitle">
<i class="fa fa-comments"></i>
<h1><%= @receiver.profile.first_name %> <%= @receiver.profile.last_name %></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 %>
<% end %>
</div>
<div class="chatboxinput">
<%= form_for([@conversation, @message], :remote => true, :html => {id: "conversation_form_#{@conversation.id}"}) do |f| %>
<%= f.text_area :body, class: "chatboxtextarea", "data-cid" => @conversation.id %>
<% end %>
</div>
<%= subscribe_to conversation_path(@conversation) %>
(This last line is for private_pub gem)