insiki
@insiki
broken pipe

Как создать дочерний объект при связи self reference?

Есть модель Task с самоприсоединением:
class Task < ActiveRecord::Base
  has_many    :subtasks, class_name: 'Task', foreign_key: "parent_id"
  belongs_to  :parent, class_name: 'Task'
  belongs_to  :user
  belongs_to  :project
end

Схема:
class CreateTasks < ActiveRecord::Migration
  def change
    create_table :tasks do |t|
      t.string  :title
      t.text    :description
      t.string  :priority
      t.string  :status
      t.date    :scheduled
      t.date    :deadline
      t.integer :user_id
      t.integer :project_id

      t.references  :parent, index: true
      t.timestamps null: false
    end
  end
end

Есть задачи (tasks), есть подзадачи (subtasks), есть ключ для связи - parent_id.
Что хочу:
При переходе на созданную таску (она уже создана!) - экшн tasks#show (путь /task/:id), помимо её описания ниже иметь возможность добавления подзадачи (subtask).
В коде, без передачи params, это вероятно выглядело бы так:
@task = Task.find(params[:id])
@task.subtasks.new
@task.save

Но как это делается на практике? Создается SubtasksController и в нем описываются экшены?
Добавляются не RESTful-экшены в TasksController? Или что-то другое? :)

Нагуглил пока видео с RailsCasts, но не знаю, мой ли случай.
  • Вопрос задан
  • 299 просмотров
Решения вопроса 1
insiki
@insiki Автор вопроса
broken pipe
Ответ:
Достаточно 1-го контролера - TasksController.
В модель добавляем параметр "accepts_nested_attributes_for", который при создании объекта передает дополнительные параметры.
class Task < ActiveRecord::Base
  has_many    :subtasks, class_name: 'Task', foreign_key: "parent_id"
  belongs_to  :parent, class_name: 'Task'
  accepts_nested_attributes_for :subtasks, allow_destroy: true
  belongs_to  :user
  belongs_to  :project
end

В контроллер добавляем дополнительные атрибуты для подзадачи:
def task_params
  params.require(:task).permit(:title, :description, :priority, :status, :scheduled, :deadline, subtasks_attributes: [:title])
end

Сама же форма для создания подзадач выглядит так:
<%= simple_form_for @task do |t| %>
  <%= t.simple_fields_for :subtasks, @task.subtasks.build do |f| %>
    <div class="form-inputs">
      <%= f.input :title %> 
    </div>
    <div class="form-actions">
      <%= f.button  :submit %>
    </div>
  <% end %>
<% end %>
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
premas
@premas
Full-stack web-developer
Если идете по RailsWay, то у вас должно быть 2 контроллера. И если делайте роутинг ресурсами, то вложите subtasks в tasks.

Если отходите от RailsWay в сторону проектирования API для ajax-обмена json-данными, то делайте как удобно вам.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы