在rails(belongs_to)中创建子模型并预先设置父ID

时间:2011-01-16 02:41:26

标签: ruby-on-rails activerecord models formtastic

我确定我错过了一些简单的东西,但是没有意识到Rails中的正确术语,我找不到我想要的东西......

Project模型has_many TaskTask belongs_to a Project

我的routes.rb

resources :projects
resources :tasks

我可以创建/编辑/修改Projects就好了,我也可以修改Tasks ...但我似乎无法弄清楚如何创建新的Task ,在执行此操作时指定正确的Project

我的Project页面(例如/ projects / 2)有一个添加任务链接,该链接转到/ task / new,所以我正在丢失连接。我不想创建嵌套资源,因为Tasks一旦创建,将由其ID唯一标识,并且将来也可以使用其他模型。

这里有快速解决方法吗?

编辑嗯,我已经设法解决了这个问题......它太丑了,太可怕了,我不确定为什么它必须这样,但它确实有效。

我的路线:

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 %>

我不想将项目框放在表单上,​​我仍然不确定为什么必须这样做,以及为什么我需要采取:创建 out 嵌套路线。对于这样一个共同的任务来说,它看起来也很费劲,但它确实有效,所以......我想这一切都很好。

2 个答案:

答案 0 :(得分:2)

确保在新任务操作中通过项目构建新任务,以便它已经分配了项目ID。这应该使你的表单生成器表现得很好并且做正确的事情。

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 :(得分:1)

IT听起来像你想要的只是一个用于创建任务的嵌套路线。

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 %>