Reputation: 3534
I'm working on a Rails 3 task demo project in which each instance of Project
has many tasks
, and instances of Task
belong to one project
. However, this latter relationship is optional, although it's defined in the Task
model as belongs_to :project
.
Essentially, I want to be able to have routes like the following:
example.com/tasks/1
example.com/tasks/new
example.com/project/1/tasks/1
example.com/project/1/tasks/new
I'm not sure if this is possible or even good practice. Really what's most important is for me to be able to create project-less tasks from within the general tasks#index
action, and tasks belonging to a project from within the project#show
action via links to new
actions.
I've read Rails Routing from the Outside In, but it didn't really explain what I'm going for.
Any help would be greatly appreciated.
Upvotes: 3
Views: 1549
Reputation: 64147
This is actually more common than you think. Here is a solution:
class TasksController < ApplicationController
before_filter :get_project
before_filter :get_tasks
private
def get_project
@project = Project.find(params[:project_id]) if params[:project_id]
end
def get_tasks
@tasks = (@project) ? @project.tasks : Task
end
end
From there you, you would always reference @tasks when you want to get the tasks.
So for an example:
def new
@tasks.new(params[:task])
end
Would yield correct results whether you are nested or not.
In the case of nested, it would be like calling:
@projects.tasks.new(params[:task])
and without nested, it would be like calling:
Task.new(params[:task])
Upvotes: 3
Reputation: 48626
The routes do not relate with associations. You can have any routes you like, even if you do not have any associations. And your routes seem good.
The association is a convenience thing. It makes the programmer's life easier. If you even need to write something like :
task.projects
Then, you have to have a has_many(or other) association between tasks/projects. This has many is the one that allows you to do task.projects. If you did not have the association, you would have to use a finder.
Upvotes: 0