尝试从项目配置文件创建任务时找不到 'id'= 的项目

Couldn't find Project with 'id'= when trying to create a Task from Project profile

我有一个项目模型和一个任务模型,但是一个任务可以有多个项目,反之亦然...所以我在两者之间创建了一个关系模型。现在从项目配置文件中,我希望能够创建一个任务并自动让它创建任务以及新任务与创建它的项目之间的关系。

然而,当我尝试完成此操作时,出现以下错误:

ActiveRecord::RecordNotFound in TasksController#create
Couldn't find Project with 'id'=

用户在项目显示页面上单击 link 到 'submit new task'。我意识到我没有以某种方式传递项目 ID,但我似乎无法弄清楚如何执行此操作,因为我正在使用 TaskRelationship 模型来关联任务和项目(我没有将任务嵌套在项目中在我的路线中)。

views/projects/show.html.erb:

<%= link_to "+ Submit New Task", new_task_path, :class => "btn btn-info col-md-12" %>

从新任务视图中,我需要创建任务以及任务与项目之间的关系。

views/tasks/new.html.erb:

<div class="container sign-in-register">
    <div class="authform">

           <%= form_for @task, :html => {:multipart => true} do |f| %>

          <h3>Submit new task to this project...</h3><br/>

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

            <%= f.label :Title %>
            <%= f.text_field :title, class: 'form-control' %>

            <%= f.label :Description %>
            <%= f.text_area :description, class: 'form-control' %>

            <br clear="all">

            <%= f.submit "Add this Task", class: "btn btn btn-info" %>
          <% end %>

    </div>
</div>

任务关系模型(links 任务到项目):

class TaskRelationship < ActiveRecord::Base
  belongs_to :taskproject, class_name: "Project"
  belongs_to :projecttask, class_name: "Task"
  validates :taskproject_id, presence: true
  validates :projecttask_id, presence: true
end

项目模型:

class Project < ActiveRecord::Base
  belongs_to :owner, :foreign_key=>'user_id', :class_name=>'User'

  has_many :tasks
  has_many :taskrelationships, foreign_key: "taskproject_id", dependent: :destroy
  has_many :projecttasks, through: :taskrelationships, source: :projecttask

  validates :title, presence: true
  validates :background, presence: true

  def related?(some_task)
   taskrelationships.find_by_projecttask_id(some_task.id)
  end

  def relate!(some_task)
   self.taskrelationships.create!(projecttask_id: some_task.id)
  end

end

任务模型:

class Task < ActiveRecord::Base
  belongs_to :owner, :foreign_key=>'user_id', :class_name=>'User'

  has_many :projects
  has_many :reverse_taskrelationships, foreign_key: "projecttask_id",
                                   class_name: "TaskRelationship",
                                   dependent: :destroy
  has_many :taskprojects, through: :reverse_taskrelationships, source: :taskproject

  validates :title, presence: true
  validates :description, presence: true, length: { maximum: 140 }
end

任务控制器:

class TasksController < ApplicationController

  def new
    @task = Task.new
  end

  def create
    @project = Project.find(params[:taskproject_id])
    @task = current_user.own_tasks.build(task_params)
    if @task.save
      flash[:success] = "Your task has been created."
      redirect_to @task
      @project.relate!(@task) unless @project.related?(@task) # establish task relationship w/ project only if doesn't exist
    else
      render 'task'
    end
  end

private

 def task_params
      params.require(:task).permit(:title, :description, :user_id, task_relationship_attributes: [:taskproject_id, :projecttask_id])
 end

end

Task_Relationships_Controller:

class TaskRelationshipsController < ApplicationController
  before_filter :authenticate_user!

  def create
  end

  def destroy
  end

  # I assume (maybe incorrectly) that i don't need create/destroy actions but do need strong params

  private

  def task_relationship_params
    params.require(:taskrelationship).permit(:taskproject_id, :projecttask_id)
  end
end

我怎样才能传递这个正确的 ID,以便创建新任务以及任务和项目之间的新任务关系?谢谢,

更新:

我已经添加了日志以获取更多详细信息

尝试 post 时的终端日志:

Started GET "/tasks/new" for ::1 at 2016-04-15 19:55:54 -0500
Started GET "/tasks/new" for ::1 at 2016-04-15 19:55:54 -0500
Processing by TasksController#new as HTML
Processing by TasksController#new as HTML
  Rendered shared/_error_messages.html.erb (0.1ms)
  Rendered shared/_error_messages.html.erb (0.1ms)
  Rendered tasks/new.html.erb within layouts/application (24.5ms)
  Rendered tasks/new.html.erb within layouts/application (24.5ms)
  Rendered layouts/_shim.html.erb (0.0ms)
  Rendered layouts/_shim.html.erb (0.0ms)
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" =   ORDER BY "users"."id" ASC LIMIT 1  [["id", 4]]
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" =   ORDER BY "users"."id" ASC LIMIT 1  [["id", 4]]
  Rendered layouts/_navigation_links.html.erb (1.6ms)
  Rendered layouts/_navigation_links.html.erb (1.6ms)
  Rendered layouts/_header.html.erb (2.9ms)
  Rendered layouts/_header.html.erb (2.9ms)
  Rendered layouts/_footer.html.erb (0.0ms)
  Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 192ms (Views: 185.6ms | ActiveRecord: 1.0ms)
Completed 200 OK in 192ms (Views: 185.6ms | ActiveRecord: 1.0ms)




Started POST "/tasks" for ::1 at 2016-04-15 19:55:59 -0500
Started POST "/tasks" for ::1 at 2016-04-15 19:55:59 -0500
Processing by TasksController#create as HTML
Processing by TasksController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"DGGG+zWPMbB7OwZz8oCVLB5O6sMfTe/Orj6KfeP6mrveOH0ImAP4aow0gufqefOdwsp8v4GDEt8ppJiL4CvQVg==", "task"=>{"title"=>"test", "description"=>"test"}, "commit"=>"Add this Evidence"}
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"DGGG+zWPMbB7OwZz8oCVLB5O6sMfTe/Orj6KfeP6mrveOH0ImAP4aow0gufqefOdwsp8v4GDEt8ppJiL4CvQVg==", "task"=>{"title"=>"test", "description"=>"test"}, "commit"=>"Add this Evidence"}
  Project Load (0.3ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."id" =  LIMIT 1  [["id", nil]]
  Project Load (0.3ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."id" =  LIMIT 1  [["id", nil]]
Completed 404 Not Found in 2ms (ActiveRecord: 0.3ms)
Completed 404 Not Found in 2ms (ActiveRecord: 0.3ms)

ActiveRecord::RecordNotFound (Couldn't find Project with 'id'=):
  app/controllers/tasks_controller.rb:8:in `create'

ActiveRecord::RecordNotFound (Couldn't find Project with 'id'=):
  app/controllers/tasks_controller.rb:8:in `create'

在您的控制器语句 Project.find(params[:taskproject_id]) 中,看起来 params[:taskproject_id] 为零。查看表单视图中的代码,传递给控制器​​的参数应该是 params[:id]。也不清楚 task_params 在哪里定义

如果您仍然遇到错误,请检查您提交表单时输出的日志中的参数,并post在此处检查它们。

1) 您需要以某种方式将项目 ID 传递给 TasksController#new。 一种方法是将其作为请求的一部分传递 URL,类似于:

<host>/tasks/new?project_id=<project ID>

这将使它在请求的 params 变量中可用。

2) 在您的 TasksController#new 操作中,将 project_idparams 传递到视图。最简单的方法是使用实​​例变量:

@project_id = params[:project_id]

有一种只将一个对象传递给视图的理念,这里我们传递 2:@task 和 @project_id。我不担心,但您可能想阅读有关表单对象的内容:https://robots.thoughtbot.com/activemodel-form-objects

3) 在您的表单上添加一个带有项目 ID 的隐藏字段。因为@project_id 不是@task 模型的一部分,所以我们将使用输入标签助手而不是基于表单的助手:

<%= hidden_field_tag 'project_id', @project_id %>

API 文档:http://apidock.com/rails/ActionView/Helpers/FormTagHelper/hidden_field_tag

现在,当用户单击 submit 按钮时,@project_id 的值将作为 params[:project_id] 传递给 #create 操作。

4) 更改 TasksController#create 操作中的参数。 project_id 将嵌套在 task 参数中:

@project = Project.find(参数[:project_id])

5) 您需要创建您的 TaskRelationship 关系。有几种方法可以做到这一点。我通常使用 build:

@task.taskprojects.build(project: @project)

所以你的 #create 操作看起来像:

@project = Project.find(params[:project_id])
@task = current_user.own_tasks.build(task_params)
@task.taskprojects.build(project: @project)
if @task.save
...