# Nested Routes allow for actions only if IDs match?

**URL:** <https://www.ruby-forum.com/t/nested-routes-allow-for-actions-only-if-ids-match/170822>\
**Category:** Rails\
**Created:** [June 23, 2009, 8:02am UTC](https://www.ruby-forum.com/t/nested-routes-allow-for-actions-only-if-ids-match/170822 "2009-06-23T08:02:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ahad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/bbce88/32.png) [@ahad](https://www.ruby-forum.com/u/ahad)\
**Post date:** [June 23, 2009, 8:02am UTC](https://www.ruby-forum.com/t/nested-routes-allow-for-actions-only-if-ids-match/170822/1 "2009-06-23T08:02:11Z")

</div>

Hello,

I’m encountering a very strange issue and I’ve identified behavior I  
don’t quite understand. I have a design in which a “full model” exists  
with sub-screens for each of the pages worth of data input. Each screen  
goes through validation, and then updates the overall model with the  
validated input, as well as saving the screen’s information to a  
specific “screen” table.

For instance:

class FullQuoteHoModel \< ActiveRecord::Base  
has\_one :full\_quote\_ho  
has\_one :full\_quote\_ho\_loc  
has\_one :full\_quote\_ho\_cov  
has\_one :full\_quote\_ho\_additional\_coverage

end

class FullQuoteHo \< ActiveRecord::Base  
belongs\_to :full\_quote\_ho\_model  
end

class FullQuoteHoLoc \< ActiveRecord::Base  
belongs\_to :full\_quote\_ho\_model  
end

class FullQuoteHoCov \< ActiveRecord::Base  
belongs\_to :full\_quote\_ho\_model  
end

class FullQuoteHoAdditionalCoverage \< ActiveRecord::Base  
belongs\_to :full\_quote\_ho\_model  
end

FullQuoteHoModel is the “entire” model, with each of the others as  
“sub-screens” that accept inputs, validate them, save the values to  
their tables, and also update the accepted, validated inputs into the  
“entire” model.

I only want index/show/new/destroy in the FullQuoteHoModel, and I only  
want new/create/edit/update in the sub-screens. I do this in the routes  
file as follows:

map.resources :full\_quote\_ho\_models, :except =\> [:edit, :update,  
:create], :requirements =\> {:id =\> /[0-9]+/} do |full\_quote\_ho\_model|  
full\_quote\_ho\_model.resources :full\_quote\_ho\_additional\_coverages,  
:only =\> [:new, :create, :edit, :update], :requirements =\> {:id =\>  
/[0-9]+/}, :name\_prefix =\> nil  
full\_quote\_ho\_model.resources :full\_quote\_ho\_covs, :only =\> [:new,  
:create, :edit, :update], :requirements =\> {:id =\> /[0-9]+/},  
:name\_prefix =\> nil  
full\_quote\_ho\_model.resources :full\_quote\_ho\_locs, :only =\> [:new,  
:create, :edit, :update], :requirements =\> {:id =\> /[0-9]+/},  
:name\_prefix =\> nil  
full\_quote\_ho\_model.resources :full\_quote\_hos, :only =\> [:new,  
:create, :edit, :update], :requirements =\> {:id =\> /[0-9]+/},  
:name\_prefix =\> nil  
end

Now, when I create a new full quote ho model from the FullQuoteHoModel  
index screen, I can create each of the screens just fine, as well as the  
overall model (for testing purposes, there is no validation above, so I  
create empty records that are assigned system-generated IDs).

When I access any screen from the FullQuoteHoModel, if it has the same  
ID path as the FullQuoteHoModel, things show up and work as intended.  
However, if the ID of the screen is not the same as the  
FullQuoteHoModel, then I receive the following error:

ActionController::RoutingError in Full\_quote\_hos#edit

Showing app/views/full\_quote\_hos/edit.html.erb where line #3 raised:

full\_quote\_ho\_url failed to generate from {:action=\>“update”,  
:full\_quote\_ho\_model\_id=\>#\<FullQuoteHo id: 4, inception\_date: “”,  
building\_construction: nil, protection\_class: nil, territory: “”,  
policy\_form: “”, replacement\_cost\_on\_contents: “”, occupancy\_type: “”,  
building\_type: “”, applicants\_first\_name: “”, applicants\_middle\_initial:  
“”, applicants\_last\_name: “”, applicants\_date\_of\_birth: “”,  
applicants\_ssn: “”, coapplicants\_first\_name: “”,  
coapplicants\_middle\_initial: “”, coapplicants\_last\_name: “”,  
coapplicants\_date\_of\_birth: “”, coapplicants\_ssn: “”,  
property\_address\_1: “”, property\_address\_2: “”, property\_zip\_code: “”,  
property\_county: “”, property\_city: “”, property\_state: “”,  
property\_city\_limits: “”, property\_address\_how\_long: “”,  
mailing\_address\_1: “”, mailing\_address\_2: “”, mailing\_zip\_code: “”,  
mailing\_county: “”, mailing\_city: “”, mailing\_state: “”,  
previous\_address\_1: “”, previous\_address\_2: “”, previous\_zip\_code: “”,  
previous\_county: “”, previous\_city: “”, previous\_state: “”,  
currently\_insured: “”, current\_carrier: “”, created\_at: “2009-06-23  
05:45:03”, updated\_at: “2009-06-23 05:45:03”, full\_quote\_ho\_model\_id:  
3\>, :controller=\>“full\_quote\_hos”}, expected: {:action=\>“update”,  
:controller=\>“full\_quote\_hos”}, diff:  
{:full\_quote\_ho\_model\_id=\>#\<FullQuoteHo id: 4, inception\_date: “”,  
building\_construction: nil, protection\_class: nil, territory: “”,  
policy\_form: “”, replacement\_cost\_on\_contents: “”, occupancy\_type: “”,  
building\_type: “”, applicants\_first\_name: “”, applicants\_middle\_initial:  
“”, applicants\_last\_name: “”, applicants\_date\_of\_birth: “”,  
applicants\_ssn: “”, coapplicants\_first\_name: “”,  
coapplicants\_middle\_initial: “”, coapplicants\_last\_name: “”,  
coapplicants\_date\_of\_birth: “”, coapplicants\_ssn: “”,  
property\_address\_1: “”, property\_address\_2: “”, property\_zip\_code: “”,  
property\_county: “”, property\_city: “”, property\_state: “”,  
property\_city\_limits: “”, property\_address\_how\_long: “”,  
mailing\_address\_1: “”, mailing\_address\_2: “”, mailing\_zip\_code: “”,  
mailing\_county: “”, mailing\_city: “”, mailing\_state: “”,  
previous\_address\_1: “”, previous\_address\_2: “”, previous\_zip\_code: “”,  
previous\_county: “”, previous\_city: “”, previous\_state: “”,  
currently\_insured: “”, current\_carrier: “”, created\_at: “2009-06-23  
05:45:03”, updated\_at: “2009-06-23 05:45:03”, full\_quote\_ho\_model\_id:  
3\>}

Extracted source (around line #3):

1:

# Editing Full Quote Homeowners: Basic Information
  
2:  
3: \<% form\_for(@full\_quote\_ho) do |f| %\>  
4: \<%= error\_messages\_for :full\_quote\_ho, :header\_message =\>  
“#{@full\_quote\_ho.errors.count} validation errors prohibited this Full  
Quote Screen from being validated.”, :message =\> “Please correct the  
fields in red and try again.” %\>  
5:

This is an issue because currently, a user can create a new  
FullQuoteHoModel, fill out two screens, then hit Back and go to the  
FullQuoteHoModel index, maybe create a new FullQuoteHoModel, fill out  
all screens, then decide to return to the first one and create the  
remaining two screens. The IDs are then out of sync (which isn’t  
unintended behavior - technically speaking, no matter what the ID of the  
screen, it belongs to one and only one FullQuoteHoModel) and trying to  
go back and edit that screen doesn’t show up. Is this a routing issue  
(the generated URLs, maybe)? Or something else?

The index page shows the ability to create or edit screens as follows  
per FullQuoteHoModel record:

```
<% @full_quote_ho_models.each do |full_quote_ho_model| %>
<tr>
  <td><%=h full_quote_ho_model.inception_date %></td>
  <td><%=h full_quote_ho_model.policy_form %></td>
  <td><%=h full_quote_ho_model.applicants_first_name %></td>
  <td><%=h full_quote_ho_model.applicants_middle_initial %></td>
  <td><%=h full_quote_ho_model.applicants_last_name %></td>
  <td><%=h full_quote_ho_model.applicants_ssn %></td>
  <td><%=h full_quote_ho_model.property_address_1 %></td>
  <td><%=h full_quote_ho_model.property_address_2 %></td>
  <td><%=h full_quote_ho_model.property_zip_code %></td>
  <td><%=h full_quote_ho_model.property_county %></td>
  <td><%=h full_quote_ho_model.property_city %></td>
  <td><%=h full_quote_ho_model.property_state %></td>
</tr>
<tr>
  <td colspan="1"><%= link_to 'Show', full_quote_ho_model %></td>

  <% if full_quote_ho_model.full_quote_ho != nil %>
  <td colspan="2"><%= link_to 'Edit Basic Information',

```

edit\_full\_quote\_ho\_path(full\_quote\_ho\_model.id,  
full\_quote\_ho\_model.full\_quote\_ho.id) %\>  
\<% else %\>

\<%= link\_to ‘Continue Basic Information’,  
new\_full\_quote\_ho\_path(full\_quote\_ho\_model.id) %\>  
\<% end %\>

```
  <% if full_quote_ho_model.full_quote_ho_loc != nil %>
  <td colspan="2"><%= link_to 'Edit Locations',

```

edit\_full\_quote\_ho\_loc\_path(full\_quote\_ho\_model.id,  
full\_quote\_ho\_model.full\_quote\_ho\_loc.id) %\>  
\<% else %\>

\<%= link\_to ‘Continue Locations’,  
new\_full\_quote\_ho\_loc\_path(full\_quote\_ho\_model.id) %\>  
\<% end %\>

```
  <% if full_quote_ho_model.full_quote_ho_cov != nil %>
  <td colspan="2"><%= link_to 'Edit Coverages',

```

edit\_full\_quote\_ho\_cov\_path(full\_quote\_ho\_model.id,  
full\_quote\_ho\_model.full\_quote\_ho\_cov.id) %\>  
\<% else %\>

\<%= link\_to ‘Continue Coverages’,  
new\_full\_quote\_ho\_cov\_path(full\_quote\_ho\_model.id) %\>  
\<% end %\>

```
  <% if full_quote_ho_model.full_quote_ho_additional_coverage != nil

```

%\>

\<%= link\_to ‘Edit Additional Coverages’,  
edit\_full\_quote\_ho\_additional\_coverage\_path(full\_quote\_ho\_model.id,  
full\_quote\_ho\_model.full\_quote\_ho\_additional\_coverage.id) %\>  
\<% else %\>  
\<%= link\_to ‘Continue Additional Coverages’,  
new\_full\_quote\_ho\_additional\_coverage\_path(full\_quote\_ho\_model.id)  
%\>  
\<% end %\>

```
  <td colspan="1"><%= link_to 'Destroy', full_quote_ho_model,

```

:confirm =\> ‘Are you sure?’, :method =\> :delete %\>

If I try and alter the generated URLs to not include IDs, I receive  
errors. I know the ordering of the IDs is appropriate. The pathing  
should be as it currently is: /full\_quote\_ho\_models/#/full\_quote\_ho/# or  
/full\_quote\_ho\_models/#/full\_quote\_ho\_locs/#, etc.

Has anyone seen this behavior before?

---

<div class="post-metadata">

**Author:** ![ahad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/bbce88/32.png) [@ahad](https://www.ruby-forum.com/u/ahad)\
**Post date:** [June 23, 2009, 7:30pm UTC](https://www.ruby-forum.com/t/nested-routes-allow-for-actions-only-if-ids-match/170822/2 "2009-06-23T19:30:18Z")

</div>

Have you tried explicitly setting the URL to post to in the form\_for?  
From the trace, it looks like it’s trying to generate a route to  
edit\_full\_quote\_ho without specifying the parent model.  
[@full\_quote\_ho\_model, @full\_quote\_ho] might work as well.

–Matt J.

On Jun 23, 2:02 am, Ahad A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![ahad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/bbce88/32.png) [@ahad](https://www.ruby-forum.com/u/ahad)\
**Post date:** [June 24, 2009, 7:25am UTC](https://www.ruby-forum.com/t/nested-routes-allow-for-actions-only-if-ids-match/170822/3 "2009-06-24T07:25:11Z")

</div>

Matt J. wrote:

> Have you tried explicitly setting the URL to post to in the form\_for?  
> From the trace, it looks like it’s trying to generate a route to  
> edit\_full\_quote\_ho without specifying the parent model.  
> [@full\_quote\_ho\_model, @full\_quote\_ho] might work as well.
> 
> –Matt J.
> 
> On Jun 23, 2:02ï¿½am, Ahad A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

No, I haven’t tried explicitly setting the URL. I’m trying to do this  
the proper way within the Rails framework, and I wanted to utilize the  
helpers/paths.

[@full\_quote\_ho\_model, @full\_quote\_ho] didn’t work and caused similar  
issues.

As I said earlier, if the IDs for the parent model and it’s nested  
models are the same, everything works fine - but if not, that’s when  
there is an error. So, I have a feeling it isn’t my view code/URLs, but  
rather the logic behind how I have things routed and/or designed.
