Необязательная маршрутизация belongs_to и Rails

#ruby-on-rails #routing #associations

#ruby-on-rails #маршруты #ассоциации

Вопрос:

Я работаю над демонстрационным проектом задачи Rails 3, в котором каждый экземпляр Project имеет много tasks , а экземпляры Task принадлежат одному project . Однако это последнее соотношение является необязательным, хотя оно определено в Task модели как belongs_to :project .

По сути, я хочу иметь возможность иметь маршруты, подобные следующим:

 example.com/tasks/1
example.com/tasks/new

example.com/project/1/tasks/1
example.com/project/1/tasks/new
  

Я не уверен, возможно ли это или даже хорошая практика. На самом деле, для меня важнее всего иметь возможность создавать задачи без проекта из общего tasks#index действия и задачи, принадлежащие проекту, из project#show действия через ссылки на new действия.

Я прочитал маршрутизацию Rails извне в, но это на самом деле не объясняет, к чему я стремлюсь.

Любая помощь была бы высоко оценена.

Ответ №1:

На самом деле это встречается чаще, чем вы думаете. Вот решение:

 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
  

Оттуда вы всегда будете ссылаться на @tasks, когда захотите получить задачи.

Итак, для примера:

 def new
  @tasks.new(params[:task])
end
  

Даст правильные результаты независимо от того, вложены вы или нет.

В случае nested это было бы похоже на вызов:

 @projects.tasks.new(params[:task])
  

и без вложенности это было бы похоже на вызов:

 Task.new(params[:task])
  

Комментарии:

1. вы могли бы сделать: Project.tasks.create(параметры[:tasks].merge({:project_id=>параметры[:id]}), где params[:task] — это просто хэш, который вы передали бы в #create.

2. Разобрался с вашим советом и связал его с Devise. После настройки маршрутов мне действительно не нужно было ничего менять сверх того, что у меня было изначально, кроме того, что новый тег link_to является link_to 'New Task', @project ? "#{@project.id}/tasks/new" : new_task_path

Ответ №2:

Маршруты не связаны ассоциациями. У вас могут быть любые маршруты, которые вам нравятся, даже если у вас нет никаких ассоциаций. И ваши маршруты кажутся хорошими.

Ассоциация — это удобство. Это упрощает жизнь программиста. Если вам даже нужно написать что-то вроде :

 task.projects 
  

Затем у вас должна быть связь has_many (или другая) между задачами / проектами. У этого есть много — это тот, который позволяет вам выполнять task.projects. Если бы у вас не было ассоциации, вам пришлось бы использовать finder.