I was talking about this problem on here about a week ago, and then had
to
break off from working on it. Returning again.
I’m having an issue with a show action on a nested resource (REST based
controllers).
The main resource (not the nested one) is Candidates
The nested resource is Canbackgrounds
To show the relevant database columns(with example):
Candidates table:
| id | user_id | …other fields |
±----±-------------±---------------------|
| 12 | 1 | |
The url for a single background (which is what I understand that to be)
would need a background, surely.
A.
Neither even comes close and throws an error loading the page.
It still needs to pass the candidate id,
However the link should be showing (in this instance)
candidates/12/canbackgrounds/28
Neither even comes close and throws an error loading the page.
It still needs to pass the candidate id,
However the link should be showing (in this instance)
candidates/12/canbackgrounds/28
Stuart
Looking at AWDWR (latest)
GET/articles/1/comments/99show
comment_url(:article_id=>1,:id=>99)
Which I interpret for my resources as
<%= link_to ‘show’, canbackground_url(:candidate_id => @candidate, :id
=> @canbackground) %>
Yet this takes me to ‘index’ and not ‘show’, Adding in :method => :get
adds
an error.
The url for a single background (which is what I understand that to
Yet this takes me to ‘index’ and not ‘show’, Adding in :method => :get
adds an error.
Stuart
Bump, sorry, can’t figure this out for a hill of beans.
Relevant routes:
map.resources :candidates do |candidate|
candidate.resources :canbackgrounds
Attempting to create a link for canbackgrounds/show.rhtml
Canbackgrounds.rb controller show action:
def show @candidate_id = params[:candidate_id] @canbackground = @candidate.canbackgrounds.find(params[:id])
…
…
end
Nothing I’m trying in the link seems to be working right -
Instead of posting all the crappy code that doesn’t work but I tried for
the
link ,
I’m thinking there should be a simple formula
A few that I’ve tried have taken me to ‘index’, but not show.
This takes me to the index page / action not the show action.
These look like non-nested resources except that they have an additional
parameter at the front for the parent.
Some other questions, though.
1)You haven’t by any chance, got:
map.resources :canbackgrounds
Nope
and
map.resources :candidates | candidate|
candidate.resources :canbackgrounds
end
at the same time ?
This is from my routes.rb
map.resources :candidates do |candidate|
candidate.resources :canpositions
candidate.resources :canbackgrounds
candidate.resources :canskills
Are you on Edge Rails or the 1.2RC gem ?
Yes , Edge rails
you do have the appropriate associations in the models ? ( candidate
If we dont get anywhere soon, feel free to mail me the whole project and
I’ll take a look and see if I can help. [gmail:alancfrancis]
Alan
I went back to AWDWR and the example shows the nested resource ,
rendered
via a partial in the primary resource. That I can do.
In the Peepcode , code (which I have along with the podcast), sort of
confusing, in that the code shows for the nested resource
a seperate index and show page / view.
In the podcast though, he nixes the show and index actions in the
controller
using partials from the primary resource.
This might be my problem as I’m trying to call the nested resource
directly
from the primary one, either through show.rhtml or index.rhtml.
As far as using partials, you wouldn’t be using nested resources in
your routes to access them, because the code to load the Canbackground
data to use in the partial would either be invoked by the
Candidates::show action or in the RHTML file itself.
Out of curiousity, what is the relationship between candidates and
backgrounds? Can one candidate have multiple background records?
As far as using partials, you wouldn’t be using nested resources in
your routes to access them, because the code to load the Canbackground
data to use in the partial would either be invoked by the
Candidates::show action or in the RHTML file itself.
Right, currently the Candidate::show action is rendering the partials
for
all the nested resources within Candidates. It uses, what
I believe is called the ‘conveinence method’ (:collection => @
candidate.nestedresource)
I think what your saying is find another method to invoke the
canbackground
record ?
Out of curiousity, what is the relationship between candidates and
backgrounds? Can one candidate have multiple background records?
From my models -
class Canbackground < ActiveRecord::Base
belongs_to :candidate
class Candidate < ActiveRecord::Base
has_many :canbackgrounds
But really in the long run, one candidate can have only one
canbackground.
I would check this probably via the user.id. However that is not
implemented as of yet.
My first suggestion would be to alter your Candidate model to use a
has_one :canbackground association. Then you can easily call @candidate.canbackground without needing a second ‘find’ call to load
the right record.
My advice would be to do away with the ‘find_candidate’ action in your
canbackgrounds_controller. The only places where you need to load the
candidate from the candidate_id are the ‘index’ and ‘new’ actions.
def index @canbackground = Candidate.find(params[:candidate_id]).canbackground
end
def new @canbackground =
Candidate.find(params[:candidate_id]).build_canbackground
end
The rest of your actions, such as ‘show’, can simply load the
canbackground by it’s ID.
def show @canbackground = Canbackground.find(params[:id])
end
HOWEVER, all this is probably moot if you’re just using a 1 to 1
relationship between Candidates and Canbackgrounds. In that case, what
I would probably do is use the candidates_controller to create both the
candidate and the associated background in one view. There’s a useful
tutorial on the Rails Forum that discusses creating multiple models in
a single view. http://railsforum.com/viewtopic.php?id=717
You don’t even need new methods in your candidates_controller file, you
can use the standard 7 CRUD actions to perform all the necessary
operations on the canbackground object in the context of the candidate.
My first suggestion would be to alter your Candidate model to use a
has_one :canbackground association. Then you can easily call @candidate.canbackground without needing a second ‘find’ call to load
the right record.
I must be losing it :), did the above suggest,
class Candidate < ActiveRecord::Base
has_one :canbackground
end
Added to candidates/show
<%= link_to ‘show’, canbackground_path(@candidate.canbackground) %>
So now, the link is backwards, in other words it’s got the id’s in the
wrong
place.
Should be (example) candidates/12/canbackgrounds/28
However it has candidates/28/canbackgrounds/12
HOWEVER, all this is probably moot if you’re just using a 1 to 1
relationship between Candidates and Canbackgrounds. In that case, what
I would probably do is use the candidates_controller to create both the
candidate and the associated background in one view. There’s a useful
tutorial on the Rails Forum that discusses creating multiple models in
a single view. http://railsforum.com/viewtopic.php?id=717
I do have them in the same view (or did)
Doing something like this:
<% 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 %>
The Peepcode podcast is pretty good, plus it also covers things like
respond_to. I need to watch it more.
There are too minor errors though in the podcast. One, it showing
scaffold_resource using singular controller names,
and second error is the route.rb where it shows the primary resource in
the
do statement as plural. AWDWR shows it as singular and
I believe that’s correct.
Glad to hear that you’ve got it working! I’ve been wrestling with
these myself for the last month as well, so I know how frustrating it
can get when there’s one or two little pieces wrong derailing the whole
application.
Alan , but what made the difference was changing the association in
Candidates from has_many :canbackgrounds
to has_one :canbackground. I can’t say why that is so, but it made the
difference.
Fair point
I’m not sure either, but it would sure be interesting to do a bit of
route spelunking and and find out
Alan , but what made the difference was changing the association in
Candidates from has_many :canbackgrounds
to has_one :canbackground. I can’t say why that is so, but it made the
difference.