我有一个项目模型和一个任务模型,但是一个任务可以有很多项目,反之亦然......所以我创建了两者之间的关系模型。现在,从项目配置文件中,我希望能够创建任务并自动创建任务以及新任务与创建项目之间的关系。
然而,当我尝试完成此操作时,我收到以下错误:
ActiveRecord::RecordNotFound in TasksController#create
Couldn't find Project with 'id'=
用户在项目展示页面上,点击“提交新任务”链接。我意识到我没有以某种方式传递项目ID,但我似乎无法弄清楚如何做到这一点因为我使用TaskRelationship模型来关联任务和项目(我没有在项目中嵌套任务)在我的路线中。)
视图/项目/ show.html.erb:
<%= link_to "+ Submit New Task", new_task_path, :class => "btn btn-info col-md-12" %>
从新任务视图中,我需要创建任务和任务与项目之间的关系。
视图/任务/ 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>
TaskRelationship Model(将任务链接到项目):
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,以便创建新任务并在任务和项目之间创建新的taskRelationship? THX,
更新:
我已添加日志以获取更多详细信息
尝试发布时终端日志:
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" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 4]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 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" = $1 LIMIT 1 [["id", nil]]
Project Load (0.3ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = $1 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'
答案 0 :(得分:3)
1)您需要以某种方式将项目ID传递给TasksController#new
。
一种方法是将其作为请求URL的一部分传递,例如:
<host>/tasks/new?project_id=<project ID>
这将使其在请求的params
变量中可用。
2)在您的TasksController#new action中,将project_id
从params
传递到视图。最简单的方法是使用实例变量:
@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 doc:http://apidock.com/rails/ActionView/Helpers/FormTagHelper/hidden_field_tag
现在,当用户点击@project_id
按钮时,#create
的值将params[:project_id]
submit
行为传递给TasksController#create
。
4)更改project_id
动作中的参数。 task
将与build
参数嵌套:
@project = Project.find(params [:project_id])
5)您需要创建TaskRelationship关系。有几种方法可以做到这一点。我通常使用@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
...
行动看起来像是:
VideoList
答案 1 :(得分:1)
在控制器语句Project.find(params[:taskproject_id])
中,params[:taskproject_id]
似乎为零。查看表单视图中的代码,传递给控制器的参数应为params[:id]
。它还不清楚定义task_params
的位置
如果您仍然收到错误,请在提交表单时检查日志输出中的参数并在此处发布。