Asarluhi
Asarluhi

Reputation: 1290

controller does not respond to Ajax

I would like to use Ajax to add a micropost to my home page without redirect as soon as it is created. I added remote: true in the form:

<%= form_for(@micropost, html: { multipart: true }, remote: true) do |f| %>

and edited the create action of the microposts controller as follows:

def create
    @micropost = current_user.microposts.build(micropost_params)
    microposts_number = current_user.microposts.where("created_at >= ?", Time.zone.now.beginning_of_day).count
    if microposts_number < 10
        if @micropost.save
            respond_to do |format|
                format.html do
                    flash[:success] = "Micropost created!"
                    redirect_to root_url
                end
                format.js
            end
        else
            @feed_items = []
            flash[:danger] = @micropost.errors.full_messages.join(', ')      
            render 'static_pages/home'
        end
    else
        flash[:danger] = "You have exceeded your daily share of microposts (10)."
        redirect_to root_url
    end
end

The microposts are shown in the home page as orded list of items, where @feed_items is a collection of microposts for current_user, thus belonging to Micropost:

<% if @feed_items.any? %>
  <ol class="microposts">
    <%= render @feed_items %>
  </ol>
  <%= will_paginate @feed_items %>
<% end %>

Therefore I created app/views/microposts/create.js.erb, using jQuery to select ol.microposts and function prepend() to add the newly created micropost to the page:

$("ol.microposts").prepend('<%= escape_javascript(render partial: @micropost) %>');

The partial _micropost.html.erb, used to build the li elements inside ol.microposts is (simplified) below:

<li id="micropost-<%= micropost.id %>">
  <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
  <span class="user"><%= link_to micropost.user.name, micropost.user %></span>
  <span class="content">
    <%= micropost.content %>
    <%= image_tag micropost.picture.url if micropost.picture? %>
  </span>
</li>

However the Micropost controller does not respond to the Ajax request but redirect to root_url, responding only to html (output from cloud9 server):

Started POST "/microposts" for 82.56.61.198 at 2017-07-14 09:44:55 +0000
Cannot render console from 82.56.61.198! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by MicropostsController#create as HTML
...

Started GET "/" for 82.56.61.198 at 2017-07-14 08:51:42 +0000
Cannot render console from 82.56.61.198! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by StaticPagesController#home as HTML

I do not understand why the create action of the Micropost controller does not respond to js format. I tried to clone partial _micropost.html.erb and use the instance variable @micropost instead of the variable micropost of the iteration, but it did not work. There are no errors in the server log.

Upvotes: 1

Views: 133

Answers (2)

Pavan
Pavan

Reputation: 33542

Processing by MicropostsController#create as HTML

It is due to the limitation of AJAX. From the Reference

Ajax uses something called an xmlhttprequest to send your data. Unfortunately, xmlhttprequests cannot post files

That said, you cannot post files via AJAX. You may need some help with Remotipart or Jquery-File-Upload

Upvotes: 2

Simple Lime
Simple Lime

Reputation: 11035

You only told the action to respond_to with format.js in your successful save path. You'll need to add a respond_to block with whatever you want to do for your js everywhere you render or redirect_to

Upvotes: 1

Related Questions