link_to_remote for REST

Currently I have a ‘show’ page that integrates various partials. I’ve now added in some css tabs and want each partial in it’s own tab. So how I’ve been loading the partials now is through this call:

<%= render :partial => “/canbackgrounds/canbackground”, :collection => @ candidate.canbackgrounds %>

I thought perhaps I could fit this into a link_to_remote call but it’s generating some parsing errors. Not sure where I need braces and / or parantheses. However more importantly, can I use this call in a link to remote ?

This is what I’m trying <%= link_to_remote (“Background”, :update => ‘candidateinfo’, {render :partial => “/canbackgrounds/canbackground”, :collection => @candidate.canbackgrounds }) %>

Maybe I’m trying to fit this in with a monkey wrench :slight_smile:

TIA Stuart

If you're using REST, you'll need to modify your link_to_remote call just a little bit:

<%= link_to_remote('Background', :url => canbackground_path(@candidate.canbackground), :method => :get) %>

The new trick is that the RESTful-style URL needs to be used, and the method needs to be specified.

The action called by canbackground_path can handle rendering the partial, or you can continue to use the :update => 'candidateinfo' target on link_to_remote.

Not sure if I"m following you entirely here. canbackgrounds is a nested resource of candidates. Yet when I try canbackground_path(@candidate.canbackground) I’m getting a no method error for canbackground.

I believe becasue canbackground is nested everything works through (retains the candidate id ) through the candidates controller. However , and I think Im fuzzy on this but in the candidates controller I added this method - def background @candidate = Candidate.find(params[:id]) render :partial => “/canbackgrounds/canbackground”, :collection => @candidate.canbackgrounds end Got a complaint though it couldn’t find without id.

Stuart

Dark Ambient wrote:

> > > If you're using REST, you'll need to modify your link_to_remote call > just a little bit: > > <%= link_to_remote('Background', :url => > canbackground_path(@candidate.canbackground), :method => :get) %> > > The new trick is that the RESTful-style URL needs to be used, and the > method needs to be specified. > > The action called by canbackground_path can handle rendering the > partial, or you can continue to use the :update => 'candidateinfo' > target on link_to_remote.

Not sure if I"m following you entirely here. canbackgrounds is a nested resource of candidates. Yet when I try canbackground_path(@candidate.canbackground) I'm getting a no method error for canbackground. I believe becasue canbackground is nested everything works through (retains the candidate id ) through the candidates controller. However , and I think Im fuzzy on this but in the candidates controller I added this method - def background @candidate = Candidate.find(params[:id]) render :partial => "/canbackgrounds/canbackground", :collection => @ candidate.canbackgrounds end Got a complaint though it couldn't find without id.

Stuart

Okay, I made a wrong assumption, since you had mentioned rest. If canbackground is a nested, RESTful resource, then canbackground_path(@candidate.canbackground) would call the 'show' action in the canbackground_controller.rb file.

What does the map.resources :candidates section of your config/routes.rb file look like?

-Jared

map.resources :candidates do |candidate| candidate.resources :canbackgrounds candidate.resources :canpositions candidate.resources :canskills

Anyway, the weird thing is there is no show action right now in the canbackgrounds controller. I set up the controllers following the peepcode rest podcast.

I was calling all those resources via one page, and via the candidates/show.rhtml, with the nested resources in partials.

So there is a canbackgrounds/_canbackground.rhtml. To show , in the candidates/show.rhtml this is the call that brings in the canbackgrounds (either new or show)

<% unless @candidate.canbackgrounds.empty? %>

<%= render :partial => “/canbackgrounds/canbackground”, :collection => @candidate.canbackgrounds %> <% end %>

<% if @candidate.canbackgrounds.empty? %> <%= link_to “Add background”, new_canbackground_url(@candidate) %> <% end %>

Stuart

Did you use the "script/generate scaffold_resource canbackground" command to create the canbackgrounds controller?

Ideally, each of those nested resources should have a matching controller with the 7 CRUD actions, and to show a candidates's background data, you would call 'GET /candidates/1/canbackgrounds', or use the canbackground_path(@candidate.canbackground) convenience method in your view.

If you'd rather use the _canbackground.rhtml partial to display the background using link_to_remote, I'd suggest something along these lines:

In canbackgrounds_controller.rb: def show   @canbackground = Canbackground.find(params[:id])

  if request.xhr?     render :update do |page|       page.replace_html 'candidateinfo', :partial => 'canbackground', :collection => @canbackground       page.visual_effect :highlight, 'candidateinfo'     end   end   # other, non-xhr triggered show content goes here end

In app/views/candidates/show.rhtml <%= link_to_remote 'Background', :url => canbackground_path(@candidate.canbackground), :method => :get %>

This assumes that canbackground_path helper is properly hooked up to trigger the show action.

I still need to go through the email and try it out.

Did you use the “script/generate scaffold_resource canbackground” command to create the canbackgrounds controller?

Yes.

Ideally, each of those nested resources should have a matching

controller with the 7 CRUD actions, and to show a candidates’s background data, you would call ‘GET /candidates/1/canbackgrounds’, or use the canbackground_path(@candidate.canbackground) convenience method in your view.

I don’t know because after seeing the peepcode podcast I read something along the same lines regarding nested resources here on the list. I believe index and show are removed. I’d like to here more about it from others.

I guess my routes are totally screwed up . Because I render the partial , I hit the link to edit -

<%= link_to “Edit”, edit_canbackground_url(:id => canbackground, :candidate_id => canbackground.candidate) %>

And it works fine , takes me ,(just for demo purposes) candidates/12/canbackgrounds/28;edit

Yet I put the link in canbackgronds.show.rthml and I get a

undefined local variable or method `canbackground’ for #<#Class:0x877dc58:0x877dc28>

So if the edit.rhtml is working right, why wouldn't the show ? This is the controller code: def show @canbackground = Canbackground.find(params[:id]) if request.xhr? render :update do |page|

    page.replace_html  'candidateinfo', :partial => 'canbackground',
    :collection => @canbackground
    page.visual_effect :highlight, 'candidateinfo'
    end
end

other, non-xhr triggered show content goes here

end

in your show.rhtml file, the link_to line should look like this: <%= link_to "Edit", edit_canbackground_url(:id => @canbackground,                                     :candidate_id => @canbackground.candidate) %>

Notice the '@' in @canbackground, this is the variable you've defined in your show action.

In the partial, you're dealing with a local variable (canbackground), but in the full-blown show view, you're dealing with an instance variable (@canbackground).

Hope this helps!

It defintely helped getting canbackgrounds/show.rhtml to work. However the link_to_remote is not working and it looks like the primary resource @candidate , the id is not getting picked up.

ActiveRecord::RecordNotFound

in CanbackgroundsController#show Couldn’t find Candidate with ID=#Canbackground:0x80faed0 RAILS_ROOT: ./script/../config/.. Application Trace | Framework Trace | Full Trace

#{RAILS_ROOT}/vendor/rails/activerecord/lib/active_record/base.rb:1027:in `find_one'
#{RAILS_ROOT}/vendor/rails/activerecord/lib/active_record/base.rb:1010:in `find_from_ids'
#{RAILS_ROOT}/vendor/rails/activerecord/lib/active_record/base.rb:416:in `find'
#{RAILS_ROOT}/app/controllers/canbackgrounds_controller.rb:126:in `find_candidate'
Request
**Parameters** : {"candidate_id"=>"#<Canbackground:0x80faed0>",
"id"=>"12"}

To show , I have a before_filter in my canbackgrounds controller , I’ve tried both using it and making an exception for the show action. Neither way is working.

canbackgrounds.rb controller excerpts:

before_filter :find_candidate

private def find_candidate @candidate_id = params[:candidate_id] redirect_to candidate_url unless @candidate_id @candidate = Candidate.find(@candidate_id) end

This is where it seems to be dying as show in the error above. I tried adding candidate_id => candidate.id to the URL hash but just thrown an error.

Stuart

Update, after seeing Rick’s reply to my related rest question - http://www.ruby-forum.com/topic/88988#170770 I have a better understanding of different strategies for nested resources.

It would probably be a good thing to understand my error above, though after banging around with it for an hour now I still can’t find out what’s wrong. So if anyone has an idea , much appreicated.

However for my intentions for the current page I am going to try and do toggle.elements.

Stuart