【问题标题】:Create a child model in rails (belongs_to) and pre-setting the parent ID在 rails (belongs_to) 中创建子模型并预先设置父 ID
【发布时间】:2011-01-16 02:41:25
【问题描述】:

我确定我遗漏了一些简单的东西,但不知道 Rails 中的正确术语,我找不到我要找的东西......

一个Project 模型has_many Task 和一个Task 属于一个Project

我的routes.rb

resources :projects
resources :tasks

我可以创建/编辑/修改Projects 就好了,我也可以编辑Tasks...但我似乎无法弄清楚如何创建一个新的Task,分配正确的@987654330 @ 这样做时。

我的Project 页面(例如/projects/2)有一个指向/task/new 的添加任务链接,所以我失去了连接。我不想做一个嵌套资源,因为Tasks,一旦创建,就可以通过他们的 ID 来唯一识别,并且在未来还有很多其他模型。

这里有快速修复吗?

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

我不想将项目框放在表单上,​​但我仍然不确定为什么必须这样做,以及为什么我需要采取 :create out嵌套路由。对于如此常见的任务,这似乎也很费力,但它确实有效,所以....我想这一切都很好。

【问题讨论】:

    标签: ruby-on-rails activerecord models formtastic


    【解决方案1】:

    确保在新任务操作中通过您的项目构建新任务,以便它带有已分配的项目 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
    

    【讨论】:

      【解决方案2】:

      听起来你想要的只是用于创建任务的嵌套路由。

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

      【讨论】:

      • 嗯,这改变了我的路线......但我还是有点麻烦。我已经对我的 TaskController 进行了更改,以便它现在通过父项目创建任务,但是......它仍然无法正常工作。 :(
      • 你知道做这种事情的任何教程,从头到尾吗?
      • augh 我已经如此接近解决这个问题了,但仍然没有骰子......这对我来说看起来一切都很好,但我的任务目标创建表单顽固地坚持在成为 /tasks 时,即使创建操作是嵌套路由......我想如果我能解决这个问题,我就会拥有它。
      • 使用 form_for([@project, @task]) 应该为您提供正确的路线。您也可以尝试 form_for(project_tasks_path(@project.id))。两者都应该工作。
      猜你喜欢
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-17
      相关资源
      最近更新 更多