javascriptruby-on-railsajaxcontrollerview-templates

Trying to AJAXify this rails 4 method call and getting 500 error


I have a table in my view: views/uploads/index.html.erb

  other code

  <div id="uploads_table">
  <table   class="table table-striped">
  <thead>
   <tr>

    <th>File name</th>

        blah
        blah
        blah

    <th>Actions</th>
     </tr>
   </thead>
   <tbody >
     <%= render (@uploads) %> <%# partial _upload.html.erb %> 
   </tbody>

Here is the partial '_upload.html.erb'

 <tr id= "uploads_table_rows">

    <td> <%= upload.sourcedata_file_name%></td>
         <% path_arr = upload.f_path.split("\/")%>


            blah
            blah
            blah

           <%end%>
       <td><%= render 'button', :upload => upload%></td>
 </tr>

Im trying to update this table as the background jobs run and the values in the tables change.

For this I have the following setup: 1) In my upload_controller.rb I have the followin method:

 before_action :set_upload, only: [:show, :edit, :update, :destroy]

   #refresh uploads table in uploads/index.html.erb
def refresh_table
    @uploads = Upload.all
    @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
    @uploads = Upload.all
    respond_to do |format|
        format.js
    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(:id, :sourcedata, :task_id, :status, :f_path, :job)
end

2) In my uploads.js.coffee I added this code

 $(document).ready ->

   # will call refresh_table every 1 second
   setInterval refresh_table, 1000

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

3) I added a file 'refresh_table.js.erb' with the following code

  $('#uploads_table').html("#{escape_javascript(render 'upload', data:@uploads)}");

4) Finally I updated my routes file with this line as the last line:

 get 'uploads_controller/refresh_table'

The I restarted the server and started the background job that updates the table values. I ran the javascript console in chrome and all I see is a these lines every 1 second

 GET http://localhost:3000/uploads_controller/refresh_table 404 (Not Found) 
jquery.js?
body=1:8707

Im not sure whats wrong. im new to AJAX and so I was wondering if someone can give me a hand with this. Thanks


UPDATE: After trying the solution posted below this is what my routes.rb looks like:

 blah 
 blah


resource :uploads do
    member do
        post "parse"
        get "refresh_table", to: "refresh_table"
    end
end


 blah
 blah

And here is an image of the Network tab as seen in my chrome browser : enter image description here

The console tab looks like this: enter image description here

Server Console out put:

 Started GET "/uploads/refresh_table" for 127.0.0.1 at 2014-01-01 10:24:42 -0500
 Processing by UploadsController#show as */*
 Parameters: {"id"=>"refresh_table"}
 Completed 500  in 1ms

 NoMethodError - undefined method `[]' for nil:NilClass:
  app/controllers/uploads_controller.rb:89:in `set_upload'

Preview tab of network: enter image description here

Preview tab: enter image description here


Solution

  • Here's your problem:

    $.ajax url: "/uploads_controller/refresh_table"
    
    -> GET http://localhost:3000/uploads_controller/refresh_table 404 (Not Found) 
    

    It should be:

    $.ajax url: "/uploads/refresh_table"
    

    Your routes should be:

    resources :uploads do 
        get "refresh_table", to: "refresh_table"
    end
    

    Ajax

    Ajax works like this:

    User request -> JS -> Ajax -> Rails
    User view    <- JS <- Ajax <- Rails
    

    It's basically a "pseudo browser"

    It takes an action / request performed by the user (click a link, do something in the view), and you handle that request with Javascript

    Ajax is called Asynchronous Javascript And XML because it sends requests on your behalf. What confuses most people is that Ajax is completely disconnected from Rails, and has to use the same routing structure as the "normal" browser

    It's best to think of it as a teleport system - your request on the client-side is "teleported" with Ajax to Rails. However, like a teleport system, you still need to know the co-ordinates & have an endpoint to connect to