Создайте дочернюю модель в rails (own_to) и предварительно установите ID родителя - PullRequest
3 голосов
/ 16 января 2011

Я уверен, что упускаю что-то простое, но не зная правильной терминологии в Rails, я не могу найти то, что ищу ....

A Projectмодель имеет_мани Task, а Task принадлежит_ Project.

Мой routes.rb имеет

resources :projects
resources :tasks

Я могу создавать / редактировать / изменять Projects просто отлично,и я также могу редактировать Tasks ... но я не могу понять, как создать новый Task, назначая при этом правильный Project.

Моя Project страница(например, / projects / 2) имеет ссылку Add Task, которая идет в / task / new, поэтому я теряю соединение.Я не хочу делать вложенный ресурс, потому что Tasks после его создания будет уникально идентифицироваться по их идентификатору, а в будущем has_many и для других моделей.

Есть ли здесь быстрое исправление?

edit Ну, мне удалось решить эту проблему ... это уродливо и ужасно, и я не уверен, почему так должно быть, но это работает.

Мои маршруты:

resources :projects do
  resources :tasks, :only => [:new]
end

resources :tasks, :except => [:new]

Мой контроллер задач:

def new
  @project = Project.find(params[:project_id])
  @task = @project.tasks.build
end

# Process the form for creating a new task.
def create
  @project = Project.find(params[:task][:project_id])
  @task = @project.tasks.build(params[:task])
  if @task.save
    flash[:success] = 'Task created.'
    redirect_to project_path(@project)
  else
    render 'new'
  end
end

И моя форма задач:

<%= semantic_form_for @task do |f| %>

<%= render 'shared/form_message', :object => f.object %>

<%= f.inputs do %>
    <%= f.input :name %>
    <%= f.input :project %>
<% end %>

<ul class="formActions">
    <li class="list"><%= link_to 'Back to list', project_path(@task.project) %></li>
    <li><%= f.submit "Save" %></li>
</ul>

<% end %>

Мне не нужно былопоместите коробку проекта в форму, и я все еще не знаю, почему я должен, а также, почему мне нужно было взять: создать из из вложенных маршрутов.Это также кажется довольно трудоемким, для такой общей задачи, но это работает, так что ... Я думаю, это все хорошо.

Ответы [ 2 ]

2 голосов
/ 16 января 2011

Убедитесь, что вы строите новую задачу через свой проект в новом действии задачи, чтобы оно сопровождалось уже назначенным идентификатором проекта.Это должно заставить ваш генератор форм работать хорошо и делать правильные вещи.

TasksController < AplicationController
  before_filter :get_project
  …
  def new
    @task = @project.tasks.build # don't use @task = Task.new here!
  end
  …
  def get_project
    @project = Project.find(params[:project_id])
  end
end

конечно, настоятельно рекомендуется использовать вложенные маршруты с этим.

resources :projects do
  resources :tasks
end
1 голос
/ 16 января 2011

Это звучит так, как будто вы хотите, чтобы это был вложенный маршрут только для создания задач.

resources :projects do
  resources :tasks, :only=>[:new, :create]
end
resources :tasks, :except=>[:new, :create]

РЕДАКТИРОВАТЬ : Вот пересмотренная версия вашего кода, которая должна быть немного чище. С небольшим заимствованием у edgerunner .

Контроллер задач:

before_filter :get_project

def new
  @task = Task.new
end

# Process the form for creating a new task.
def create
  @task = Task.new params[:task]
  @task.project_id = params[:project_id]
  if @task.save
    flash[:success] = 'Task created.'
    redirect_to project_path(@task.project_id)
  else
    render 'new'
  end
end

private

def get_project
  @project = Project.find(params[:project_id])
end

И Форма задания:

<%= form_for [@project, @task] do |f| %>

  <%= render 'shared/form_message', :object => f.object %>

  <%= f.inputs do %>
    <%= f.input :name %>
  <% end %>

  <ul class="formActions">
    <li class="list"><%= link_to 'Back to list', project_path(@task.project) %></li>
    <li><%= f.submit "Save" %></li>
  </ul>

<% end %>
...