2

I have an ajax call that works in a .js file, using:

...
update: function(){
   $.ajax({
     url: '/groups/order_links',
...

but I would rather use the route path

I made the file extension .js.erb and I tried adding:

...
update: function(){
   $.ajax({
     url: "#{order_links_groups_path}",
     ...

or

     ...
     url: "#{order_links_groups_url}",
     ...

but I am getting a 404 in either case - [HTTP/1.1 404 Not Found 76ms]
From a POST http://localhost:3000/groups/49

rake routes shows my routes include:

                   ...
                   PUT      /groups/:group_id/links/:id(.:format)      links#update
                   DELETE   /groups/:group_id/links/:id(.:format)      links#destroy
order_links_groups POST     /groups/order_links(.:format)              groups#order_links
            groups GET      /groups(.:format)                          groups#index
                   POST     /groups(.:format)                          groups#create
         new_group GET      /groups/new(.:format)                      groups#new
        edit_group GET      /groups/:id/edit(.:format)                 groups#edit

which are defined with:

resources :groups do
  resources :links
  collection do
    post 'order_links'
  end 
end 

groups_controller has

class GroupsController < ApplicationController

  ...
  def order_links
    params[:link].each_with_index do |id, index|
      Link.where(id: id).update_all(['position = ?',index+1])
    end 
    render :nothing => true
  end 
  ...

Rails 4.1

laser
  • 1,388
  • 13
  • 14
Michael Durrant
  • 93,410
  • 97
  • 333
  • 497

2 Answers2

3

"#{}" is used for string interpolation in Coffeescript so I am assuming that's an error. I assume the url where this ajax request is being made from is http://localhost:3000/groups/49 because if you don't pass in a proper url then it will use the current path.

"<%= order_links_groups_path %>" would look for a variable in ruby. This would work but JavaScript files in the assets directory are being compiled without using your apps context. Meaning order_links_groups_path will be undefined.

The answer here should help: Route helpers in asset pipeline

<% url = MyRailsApp::Application.routes.url_helpers %>
url: "<%= url.order_links_groups_url %>"
Community
  • 1
  • 1
Ahmed
  • 789
  • 6
  • 13
3

Firstly, let me explain some things for you:

--

Mime Types

Rails processes mime-types at controller-level (not middleware).

This means that if you're looking to request a resource through ajax's js mime type, you'll have to define its handling in the controller, not the routes structure.

You'll be able to read more about how Rails processes the mime types here:

If the client wants HTML, we just redirect them back to the person list. If they want JavaScript, then it is an Ajax request and we render the JavaScript template associated with this action. Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also include the person's company in the rendered XML, so you get something like ...

This means that if you're looking to process a JS response, you'll be able to do the following:

#app/controllers/groups_controller.rb
class GroupsController < ApplicationController
   def order_links
      ...
      respond_to do |format|
         format.js 
         format.html
      end
   end
end

This allows you to create / call the various responses you want, depending on the mime type you send through to the controller.

--

Ajax

In regards to the Ajax call, you need to be aware that you shouldn't use any dynamic linking in your asset pipeline. I know the Rails documentation recommends otherwise, but the fact is if you serve static assets (as is recommended in production), you'll lose the ability to call those routes.

Of course, as Ahmed suggested, you can rely on the coffeescript or erb preprocessing to allow you to use the route as you wish:

#app/assets/javascripts/application.js.coffee
update: function(){
   $.ajax({
     url: <%= order_links_groups_path %>,
     ...

This will route your javascript request, allowing you to process the mime type in the controller as you need.

Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
Richard Peck
  • 76,116
  • 9
  • 93
  • 147