This has driven me to drinking, so I'll post this question while I'm still sober...
I am attempting to use Rails to construct an API that will send json to the client to be consumed by a JavaScript framework (AngularJS or EmberJS).
The application has 3 models so far:
1. Project
2. ProjectTodo
3. ProjectTodoComment
I wanted to have url paths that I could use as endpoints for the JSON api, so I nested the resources:

I wanted to keep the html.erb view files in order to have an administrative backend that was not reliant on JavaScript.
Because of the nesting, the routes have gotten rather convoluted. Here's an example from the the ProjectTodoComments view:
<tbody>
<% @project_todo_comments.each do |project_todo_comment| %>
<tr>
<td><%= project_todo_comment.comment %></td>
<td><%= project_todo_comment.project_todo_id %></td>
<td><%= link_to 'Show', project_project_todo_project_todo_comment_path(@project, @project_todo, project_todo_comment) %></td>
<td><%= link_to 'Edit', edit_project_project_todo_project_todo_comment_path(@project, @project_todo, project_todo_comment) %></td>
<td><%= link_to 'Destroy', [@project, @project_todo, project_todo_comment], method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
By running rake routes I can show you the entire list of routes that are created:

This nesting seems to have an overly complex effect on all of the code in the app. Here is the create method of the project_todo_comments_controller:

I'm having to pass in 3 objects in order to create the comment.
My plan was to be able to create versatile routes for any situation that I would be able to use in my JSON api.
By nesting the resources, it looks as if I have all the routes that I would need.
However, what if I add another dependent model - such as a User?
If the User model has a has_many association with the Project model, than I will have to nest the models 4 layers deep.
This just seems ridiculous - not to mention unmaintainable.
My question is...
Is this the only way to go about creating a flexible JSON API in Rails that has a lot of models with relationships, or is there a better way?
EDIT
Here are the Model associations:
Project
class Project < ActiveRecord::Base
attr_accessible :title
has_many :project_todos
end
ProjectTodo
class ProjectTodo < ActiveRecord::Base
attr_accessible :project_id, :title
belongs_to :project
has_many :project_todo_comments
end
ProjectTodoComment
class ProjectTodoComment < ActiveRecord::Base
attr_accessible :comment, :project_todo_id
belongs_to :project_todo
end
Here is the entire controller for the most deeply nested model - ProjectTodoComment:
class ProjectTodoCommentsController < ApplicationController
before_action :set_project_todo_comment, only: [:show, :edit, :update, :destroy]
before_filter :load_project
before_filter :load_todo
def index
@project_todo_comments = @project_todo.project_todo_comments.all
end
def show
@project_todo_comment = @project_todo.project_todo_comments.find(params[:id])
end
def new
@project_todo_comment = @project_todo.project_todo_comments.new
end
def edit
@project_todo_comment = @project_todo.project_todo_comments.find(params[:id])
end
def create
@project_todo_comment = @project_todo.project_todo_comments.new(params[:project_todo_comment])
respond_to do |format|
if @project_todo_comment.save
format.html { redirect_to [@project, @project_todo, @project_todo_comment], :notice => 'Project todo comment was successfully created.' }
format.json { render action: 'show', status: :created, location: @project_todo_comment }
else
format.html { render action: 'new' }
format.json { render json: @project_todo_comment.errors, status: :unprocessable_entity }
end
end
end
def update
@project_todo_comment = @project_todo.project_todo_comments.find(params[:id])
respond_to do |format|
if @project_todo_comment.update_attributes(params[:project_todo_comment])
format.html { redirect_to [@project, @project_todo, @project_todo_comment], notice: 'Project todo comment was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @project_todo_comment.errors, status: :unprocessable_entity }
end
end
end
def destroy
@project_todo_comment = @project_todo.project_todo_comments.find(params[:id])
@project_todo_comment.destroy
respond_to do |format|
format.html { redirect_to project_project_todo_project_todo_comments_url }
format.json { head :no_content }
end
end
private
def load_project
@project = Project.find(params[:project_id])
end
def load_todo
@project_todo = ProjectTodo.find(params[:project_todo_id])
end
def set_project_todo_comment
@project_todo_comment = ProjectTodoComment.find(params[:id])
end
def project_todo_comment_params
params.require(:project_todo_comment).permit(:comment, :project_todo_id)
end
end