编辑轨道中的资源;如何通过id查找对象?



1(当我在edit.html.erb中使用链接"编辑"时,它的字段由第一个对象(task(的属性填充。好像我使用该方法.first而不是方法.find(id). 但是我需要编辑一个适当的对象,并不总是第一个对象。

我试图在任务控制器中进行更改:

@project = Project.find(params[:project_id])
@task = @project.tasks.find_by(project_id: params[:id])

这样:

@project = Project.find(params[:project_id])
@task = Task.find(params[:id])

并收到:

ActiveRecord::RecordNotFound in TasksController#edit (找不到 带有"id"的任务(

当尝试更改<%= form_for @task do |f| %>上的<%= form_for [@project, @task] do |f| %>时,我收到了:

任务#edit 中的 NoMethodError (未定义的方法 'task_path'(

然后我尝试更改 show.html.erb 中的链接,并且:

2(如果我按下"更新任务"按钮,我会收到:

TasksController#update 中的 NoMethodError (未定义的方法"update" 为 nil:nilClass(

在字符串中:

@task.update(task_params)

对象路径的定义是否错误?

资料来源:

任务控制器

class TasksController < ApplicationController
def edit
@project = Project.find(params[:project_id])
@task = @project.tasks.find_by(project_id: params[:id])
end
def create
@project = Project.find(params[:project_id])
@task = @project.tasks.create(task_params)
redirect_to project_path(@project)
end
def update
@project = Project.find(params[:project_id])
@task = @project.tasks.find_by(project_id: params[:id])
@task.update(task_params)
redirect_to project_path(@project)
end
def destroy
@project = Project.find(params[:project_id])
@task = @project.tasks.find(params[:id])
@task.destroy
redirect_to project_path(@project)
end
private
def task_params
params.require(:task).permit(:title, :description, :status)
end
end

编辑.html.erb

<h2>Add a task:</h2>
<%= form_for  [@project, @task] do |f| %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
...
<p>
<%= f.submit %>
</p>
<% end %>

路线.rb

Rails.application.routes.draw do
get 'welcome/index'
resources :projects do
resources :tasks
end
root 'welcome#index'
end

项目/节目.html.erb

...
<p>
<%= link_to 'Destroy task', [task.project, task],
method: :delete,
data: { confirm: 'Are you sure?' } %>
|
<%= link_to 'Edit', edit_project_task_path(@project) %> 
</p>
...

路线

welcome_index GET    /welcome/index(.:format)                       welcome#index
project_tasks GET    /projects/:project_id/tasks(.:format)          tasks#index
POST   /projects/:project_id/tasks(.:format)          tasks#create
new_project_task GET    /projects/:project_id/tasks/new(.:format)      tasks#new
edit_project_task GET    /projects/:project_id/tasks/:id/edit(.:format) tasks#edit
project_task GET    /projects/:project_id/tasks/:id(.:format)      tasks#show
PATCH  /projects/:project_id/tasks/:id(.:format)      tasks#update
PUT    /projects/:project_id/tasks/:id(.:format)      tasks#update
DELETE /projects/:project_id/tasks/:id(.:format)      tasks#destroy
projects GET    /projects(.:format)                            projects#index
POST   /projects(.:format)                            projects#create
new_project GET    /projects/new(.:format)                        projects#new
edit_project GET    /projects/:id/edit(.:format)                   projects#edit
project GET    /projects/:id(.:format)                        projects#show
PATCH  /projects/:id(.:format)                        projects#update
PUT    /projects/:id(.:format)                        projects#update
DELETE /projects/:id(.:format)                        projects#destroy
root GET    /                                              welcome#index

提前谢谢你。

Duplicate ru.stackoverflow: https://ru.stackoverflow.com/q/690120/219253

我们有一种非常具体的方式来处理属于 Rails 中另一个模型的模型。这需要了解表单、控制器、模型和视图在轨道中的工作方式。

您在 rails 中有以下声明:

resources :projects do
resources :tasks
end

这段代码说资源task属于资源project。换句话说,所有任务都有一个关联的项目,当您与tasks交互时,始终有一个/projects/:project_id附加到 URI。生成的路由结构在您的问题中。

话虽如此,在tasks控制器中,获取正在使用Project的正确方法是:

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

而且,如果您正在修改或访问现有的Task对象(:edit, :update, :destroy, :show(,则访问该Task对象的方法是:

@task = Task.find(params[:id])

现在,对表单进行编码的正确方法是:

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

这告诉表单您正在修改/创建属于@project@task。根据您是创建还是修改Taskform_form方法呈现与不同控制器方法交互的表单。

您收到NoMethodError in Tasks#edit是因为您将表单编码方式从正确的方式更改为错误的方式(未指定任务所属的项目(。

您可能收到NoMethodError in TasksController#update for nil:NilClass,因为您以错误的方式访问任务,因此nil@task

希望这有帮助!

编辑 7/12/2017 来自 @Yaraslau Khamenka

此外,您需要提供与您正在link_to编辑的任务关联的项目:

edit_project_task_path(@project, @task)

最新更新