clem
clem

Reputation: 3534

Optional belongs_to and Rails routing

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

Answers (2)

Mike Lewis
Mike Lewis

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

Spyros
Spyros

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

Related Questions