Getting Action controller unknown format error- for rails 4 + unobtrusive javascript and AJAX call

banditKing picture banditKing · Jan 3, 2014 · Viewed 16.2k times · Source

Ive got the following setup:

uploads_controller.rb:

 class UploadsController < ApplicationController
    before_action :set_upload, only: [:show, :edit, :update, :destroy] 

   # GET /uploads
   def index
     @uploads = Upload.all
 update_file_status
 @uploads = Upload.all
   end

  # GET /uploads/1
  def show
  end

  # GET /uploads/new
  def new
puts "Running uploads/new"
   @upload = Upload.new()
  end

 # GET /uploads/1/edit
def edit
end

# POST /uploads
def create

@upload = Upload.new(upload_params)
if @upload.save
    @upload.update!(:status => "1")
    @upload.update!(:f_path => "#{@upload.sourcedata.path}")
    redirect_to uploads_url, notice: "Upload for #{@upload.task.name} was successfully created with file #{@upload.sourcedata_file_name}."
    else
       redirect_to tasks_url, alert: "*** ERROR *** Upload for #{@upload.task.name} did not go through successfully. #{@upload.errors.messages}"
    end
  end

  # PATCH/PUT /uploads/1
def update
    puts "Update method in Uploads controller received params = #{params.inspect}"
    puts "params[:upload][:job] = #{params[:upload][:job].inspect}"
    if (params[:upload][:job] == "parse")
        puts "Passed params[:job]== \"parse\" "

        redirect_to uploads_url, notice: "Parsing data from #{@upload.sourcedata_file_name}....."
        @upload.delay.add_data_to_DB()
    else
        if @upload.update(upload_params)
            redirect_to uploads_url, notice: "#{@upload.sourcedata_file_name} was updated"
        else
            redirect_to uploads_url, notice: "ERRRO #{@upload.sourcedata_file_name} could NOT be updated"
        end
    end
end


  # DELETE /uploads/1
  def destroy
     @upload.destroy
redirect_to uploads_url, notice: 'Couldnt parse file #{@upload.sourcedata_file_name}'
  end

# GET /uploads/refresh_table
def refresh_table
    @uploads = Upload.all
    update_file_status
    @uploads = Upload.all
    respond_to do |format|
        format.js # template marked refresh_table.js.erb will be evoked
        #format.html {redirect_to uploads_url}          
    end
end


  private
   # Use callbacks to share common setup or constraints between actions.
   def set_upload
     @upload = Upload.find(params[:upload][:id])
   end

   # Only allow a trusted parameter "white list" through.
   def upload_params
params.require(:upload).permit(:sourcedata, :task_id, :status, :f_path, :job)
   end

def update_file_status
@uploads.each do |u|
    if(File.exist?(u.f_path))
        puts "File #{u.sourcedata_file_name} exists"
    else
        puts "File #{u.sourcedata_file_name} has been removed"
        u.update!(:status => "-1")
    end
end
end

   end

Then I have routes.rb containing these lines:

 match 'uploads/refresh_table', to: 'uploads#refresh_table', via: :get 
 resources :uploads

uploads.js.coffee:

 $(document).ready ->
    # will call refresh_table every 1 second
    setInterval refresh_table, 5000

 refresh_table = ->
    $.ajax url: "/uploads/refresh_table"

views/uploads/index.html.erb

 <table class="table table-striped">
   <thead>
     <tr>

  <th>File name</th>
  <th>Upload Date, Time</th>
  <th>File Type</th>
  <th>Program Dates in file</th>
  <th>Total Rows</th>
  <th>Rows read</th>
  <th>Completed</th>
  <th>Status</th>
  <th>Actions</th>
     </tr>
   </thead>
   <tbody>
     <%= render (@uploads)%> <%# partial _upload.html.erb %> 
   </tbody>

 </div>
 </table>

partial views/uploads/_upload.html.erb

  <tr id= "uploads_table_rows">

    <td> <%= upload.sourcedata_file_name%></td>
         <% path_arr = upload.f_path.split("\/")%>
    <td><%= path_arr[-3..-2].join(", ").gsub!("_", "\:")%></td>
    <td> <%= upload.sourcedata_content_type%></td>
    <td> <%= upload.date_ranges.pluck(:date_range).join(", ")%>
    <td> <%= upload.total_rows%></td>
    <td> <%= upload.rows_completed%></td>
    <td> <%= number_to_percentage(upload.percentage_complete, :precision => 0)%></td>
    </td>
    <%if (upload.status == 0 ) %>
        <td>Error </td>
    <%elsif (upload.status == 1 ) %>
        <td>File saved on server</td>
    <%elsif (upload.status == 3 ) %>
        <td>File is being parsed </td>  
    <%elsif (upload.status == 2 ) %>
        <td>File data already in Database </td> 
    <%else%>
        <td>File doesn't exist on Server</td>   
    <%end%>
        <td><%= render 'button', :upload => upload%></td>
  </tr>

then I have views/uploads/refresh_table.js.erb

 $('#uploads_table_rows').html("<%=escape_javascript(render(@uploads)) %>");

When I navigate to

  some_url/uploads/refresh_table

I get an error in the browser:

ActionController::UnknownFormat
 Request parameters 
 {"controller"=>"uploads", "action"=>"refresh_table"}

server output is:

 Started GET "/uploads/refresh_table" for 127.0.0.1 at 2014-01-02 21:10:26 -0500
 Processing by UploadsController#refresh_table as HTML
  Upload Load (0.3ms)  SELECT `uploads`.* FROM `uploads`

 Completed 500  in 2ms

 ActionController::UnknownFormat - ActionController::UnknownFormat:

Ive been trying to debug this and make this work for 2 days with various approaches but unsuccessfully. Finally I know that the routing here works but somehow now the javascript view is not being evoked.

Can someone please assit. Thanks

Answer

arun15thmay picture arun15thmay · Jan 3, 2014

Try the following code in uploads.js.coffee

$.ajax url: "/uploads/refresh_table", format: 'js'

Your action handles only ajax requests. But the ajax request is being received at the server end as HTML request meaning it is not ajax request.