Problem domain
- We have
ProjectsandMilestones - Once created, a
Milestonehas aProject
Routing
In my original approach, I had something like:
resources :projects do
resources :milestones
end
So all the RESTful routes looked like: projects/PROJ_ID/milestones/ID
This was getting a bit long for my liking and you don’t need the Project ID all the time: only just when you create the Milestone.
Now, the routes look like:
resources :projects do
resources :milestones, :only => [:new, :create]
end
resources :milestones, :except => [:new, :create]
When I create a new Milestone (first route):
- I use the nested resource
- This is so as to get the
Project ID - We are creating a new
Milestone, we need aProject ID
With other Milestone operations (second route):
- I use standard
Milestoneresource - We’re already operating on an existing
Milestone - The
Milestonealready carries aProject ID
Problem: Rendering __form.html.erb
All is fine, except when I get to the views for new.html.erb and edit.html.erb for Milestone. These render _form.html.erb.
Original approach (all resources nested)
<%= form_for([@project, @milestone]) do |f| %>
...
<% end %>
Due to nested resource, we need to have Project and Milestone as parameters.
The same code above works fine for new and edit. because the original approach assumed Project/Milestone nested routing for all REST operations.
Current approach (only create/new nested)
We want _form.html.erb to look like this when we are creating a new Milestone:
<%= form_for([@project, @milestone]) do |f| %>
...
<% end %>
And for all other REST operations on a Milestone, we want _form.html.erb to look like this:
<%= form_for(@milestone) do |f| %>
...
<% end %>
So …
Current solution is not pretty:
- View code checks if “new” or non-“new” action called it
- Use “if” test to choose which code (as above) the view should execute
It’s not DRY, it’s messy and it feels like there should be a more elegant way.
Would appreciate any input. Very much still coming up to speed with Rails. Thanks in advance 😉
You can pass variable with you resource to
_formpartial. For example:New:
Edit:
Inside the form