1)当我使用链接"编辑"在edit.html.erb中,其字段由第一个对象(task
)的属性填充。好像我使用方法.first
而不是方法.find(id)
。
但是我需要编辑一个合适的对象,而不是第一个对象。
我试图改变TasksController:
@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])
并收到:
在TasksController中编辑ActiveRecord :: RecordNotFound #edit(无法找到 带有' id')的任务
当我尝试更改<%= form_for [@project, @task] do |f| %>
上的<%= form_for @task do |f| %>
时,我收到了:
任务编辑中的NoMethodError(未定义方法`task_path&#39;)
然后我尝试更改show.html.erb中的链接:
2)如果我按下按钮&#34;更新任务&#34;我收到:
TasksController#update中的NoMethodError(未定义方法`update&#39; for 零:NilClass)
in string:
@task.update(task_params)
对象路径定义中的错误是什么?
来源:
TasksController
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
edit.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 %>
的routes.rb
Rails.application.routes.draw do
get 'welcome/index'
resources :projects do
resources :tasks
end
root 'welcome#index'
end
项目/ show.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
提前谢谢。
重复ru.stackoverflow: https://ru.stackoverflow.com/q/690120/219253
答案 0 :(得分:0)
我们使用一种非常具体的方式来处理属于Rails中另一个模型的模型。这需要了解表单,控制器,模型和视图如何在rails中工作。
你在rails中有这个声明:
resources :projects do
resources :tasks
end
此代码表示资源task
属于资源project
。换句话说,所有任务都有一个关联的项目,当您与tasks
进行交互时,URI前面总是有一个/projects/:project_id
。由此产生的路径结构在您的问题中。
话虽如此,在您的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| %>
这告诉表单您正在修改/创建属于@task
的{{1}}。根据您是创建还是修改@project
,Task
方法会呈现与不同控制器方法交互的表单。
您收到了form_form
,因为您更改了将表单从正确的方式编码为错误的方式(不指定任务所属的项目)。
您可能收到了NoMethodError in Tasks#edit
,因为您以错误的方式访问了该任务,因此拥有NoMethodError in TasksController#update for nil:NilClass
nil
。
希望这有帮助!
来自@Yaraslau Khamenka的编辑7/12/2017
此外,您需要在@task
中提供与您正在编辑的任务相关联的项目:
link_to