0

I am uploading a file in my chat application, but on upload it is redirecting the page. I have tried in many ways to restrict it but i failed.

Please help me with your valuable response.

Attachment Model:

class Attachment < ApplicationRecord
    belongs_to :user
    belongs_to :chat

    validates_presence_of :user_id , :chat_id

    has_attached_file :attachment
    validates_attachment_content_type :attachment, content_type: /.*/
end    

Attachment Controller:

class AttachmentsController < ApplicationController
    before_action :logged_in_user
    layout false

    def create
        @chat = Chat.find(params[:chat_id])
        @attachment = @chat.attachments.build(attachment_params)
        @attachment.user_id = current_user.id
        if @attachment.save
            ActionCable.server.broadcast 'messages',
                message: @attachment.attachment,
                user: @attachment.user.name,
                action: "attachment"            
            head :ok 
        end     
    end

    private
        def attachment_params
            params.require(:post).permit(:attachment)
        end
end

Attachment View:

<%= form_for @attachment  , url: "/chats/#{@chat.id}/attachments", :remote => true,  authenticity_token: true, html: { multipart: true } do |f| %>

    <%= f.hidden_field :chat_id, value: @chat.id %>

    <input type="file" name="post[attachment]" onchange="this.form.submit();return false;" id="message_attachment" type="file">

<% end %>

Javascript for updating on Front-end:(using Rails ActionCable)

App.messages = App.cable.subscriptions.create('MessagesChannel',{
    received: function(data) {
        $('#new-messages').removeClass('hidden');
        if (data.action == "attachment") {
            return $('#new-messages').append(this.renderAttachment(data));  
        }
    },
    renderAttachment: function(data) {
        return data.message //"<li class='<%= self_or_other(data)%>'><div class='chatboxmessagecontent'><p>" + data.message + "</p>" + data.user + " • " + "</div></li>";       
    }
})

EDIT - 1

In Front End I am updating as

<% if @attachments.any? %>              
    <div id="messages">
        <%= render partial: 'attachments/attachment', collection: @attachments %>
    </div>
    <div class="hidden" id="new-messages"></div>
    <span id="istyping"></span>         
<% else %>
    <div class="hidden" id="new-messages"></div>
<% end %>

Attachment Parital

<li class="<%=  self_or_other(attachment) %>">
  <div class="chatboxmessagecontent">

    <a href="<%= attachment.attachment.url %>"  download>
        <%= image_tag attachment.attachment.url, height: '64', width: '64' %>
    </a><br/>

    <time datetime="<%= attachment.created_at %>" title="<%= attachment
    .created_at.strftime("%d %b  %Y at %I:%M%p") %>">
      <%= message_interlocutor(attachment).name %> • <%= attachment.created_at.strftime("%H:%M %p") %>
    </time>

  </div>
</li>

2 Answers2

1

I suspect the reason you are getting redirected is because you are not specifying how to respond to different request formats. I would need to see your server log for somethings along the lines of:

Started GET "/chats/#{@chat.id}/attachments" for 127.0.0.1 at 2016-09-13 15:38:23 +0900

Processing by Rails::AttachmentsController#create as HTML #<= this

You must specify how to respond to different request formats such as HTML or JS. Your form is using the remote: true param so it should be a JS request(ajax).

def create
  respond_to do |format|
    format.js do
      @chat = Chat.find(params[:chat_id])
      @attachment = @chat.attachments.build(attachment_params)
      @attachment.user_id = current_user.id
      if @attachment.save
        broadcast_attachment(@attachment)
        return head :no_content
      end
    end
  end
end

def broadcast_attachment(attachment)
  ActionCable.server.broadcast 'messages', message: attachment.attachment,
                                           user: attachment.user.name,
                                           action: 'attachment'
end

Let me know if the problem persists.

EDIT#1

When using the respond_to method, you must also specify the HTML format for some reason.

respond_to do |format|
  format.js do
    ...
  end
  format.html { ... }
end

If you just need the default behavior for HTML, you can simply use:

format.html

Shiyason
  • 759
  • 7
  • 16
1

On removing of head: ok in Controller File. It is not redirecting.

Cheers.