views:

1426

answers:

2

I'm having a consistency problem using link_to_remote in rails.

I have 2 use cases of link_to_remote, and they generate different ajax. I can't figure out why, and it is driving me crazy.

Here is use case one...

<%= link_to_remote "section-", :update => "sections", :url => {:action => :destroy, :controller => "sections", :id => @section.id } %>

This generates the appropriate ajax (as below) and works as I expect. Note that it picks up the :action param from the call and inserts it correctly in the ajax.

<a href="#" onclick="if { new Ajax.Updater('sections', '/sections/destroy/1', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('f5e50e62fafd118e4588b33c9571ea6eef864176')}); }; return false;">section-</a>

I also have another instance where I use link_to_remote, but it generates incorrect ajax. The use case is nearly identical, except the controller is different. Either way, I wouldn't expect that to result in different ajax.

The call...

<%= link_to_remote "question-", :update =>"questions-1", :url => {:action => :destroy, :controller => "questions", :id => @question.id} %>

The resulting ajax...

<a href="#" onclick="if { new Ajax.Updater('questions-1', '/questions/1', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('f5e50e62fafd118e4588b33c9571ea6eef864176')}); }; return false;">question-</a>

The obvious difference here is in the second arg to Ajax.Updater. The :action param is missing from that path. Why? This results in broken code for me, but I can't understand why this is happening. The link_to_remote calls are nearly identical.

Please point me in the right direction. Thanks.

Below is my routes.rb file...


ActionController::Routing::Routes.draw do |map|
  map.resources :questions, :has_one => :section, :collection => { :sort => :post }
  map.resources :sections, :has_many => :questions, :has_one => :form, :collection => { :sort => :post }
  map.resources :forms, :has_many => :sections

  # You can have the root of your site routed with map.root -- just remember to delete public/index.html.
  map.root :controller => "forms"

  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
end
+2  A: 

What do you get if you copy this into your view?

<%= url_for :action => :destroy, :controller => :questions, :id => @question.id %>

I suspect the problem's not really with link_to_remote, but with routing. Once url_for is returning the URL you expect, then try link_to_remote again.

Joe W.
I think you're correct and I get /questions/XX from your above snippet when I should get /questions/destroy/XX . The thing is, I don't know how to fix this routing behavior. The 'map.resources' lines look the same for questions and sections.
CJ
+1  A: 

Simply adding a :method => :delete to your link_to_remote call may be the simplest fix for you:

<%= link_to_remote "question-", :update =>"questions-1", :url => {:action => :destroy, :controller => "questions", :id => @question.id}, :method => :delete %>

This should force the call to /questions/:id to use the HTTP DELETE method. If you want the above call to generate the url /questions/destroy/:id instead I believe you would need a manual change to your routes, as the default map.resources doesn't seem to be achieving that result.

Adam Alexander
Thanks. Yes, that solves it. I discovered this just this morning and then I ran into your post.
CJ