Missing required keys rails
我正在尝试在app中创建任务表单.App有两个实体:
-
项目
belongs_to 用户 -
任务
belongs_to 项目
但是当我试图创建这个(非常基本的)表单时,我在我的视图中得到了这个错误
1 | No route matches {:action=>"index", :controller=>"tasks"} missing required keys: [:project_id] |
以下是我对此表单的看法的一部分
1 2 3 4 | <%= form_for [@project, @task],url: project_tasks_path do |f| %> <%= f.input :body,class: 'form-control' %> <%= f.submit 'Add task', class: 'btn' %> <% end %> |
这是项目控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | class ProjectsController < ApplicationController before_action :load_project, only: [:show, :edit, :update, :destroy] before_action :authenticate_user! def index @projects = current_user.projects unless current_user.nil? @task = Task.find_by(params[:project_id]) end def show @task = @project.tasks.build end def new @project = current_user.projects.new end def edit end def create @project = current_user.projects.create(project_params) if @project.save redirect_to root_path else render :new end end def update if @project.update(project_params) redirect_to @project else render :edit end end def destroy @project.destroy redirect_to projects_path end private def load_project @project = Project.find(params[:id]) end def project_params params.require(:project).permit(:name, :user_id) end end |
和任务控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | class TasksController < ApplicationController before_action :set_task, only: [:show, :edit, :update, :destroy] before_action :authenticate_user! def index @tasks = Task.where(project_id: project_id) end def show project = Project.find_by(id: params[:project_id]) @task = Task.new(project: project) end def new project = Project.find_by(id: params[:project_id]) @task = Task.new(project: project) end def edit project = Project.find_by(id: params[:project_id]) @task = Task.new(project: project) end def references respond_to do |format| if @task.valid? format.html { redirect_to root_url } format.json { render :show, status: :created, location: @task } else format.html { render :home_url } format.json { render json: @task.errors, status: :unprocessable_entity } end end end def create @project = Project.find_by(id: params[:project_id]) @task = @project.tasks.create(task_params) respond_to do |format| if @task.valid? format.html { redirect_to root_url } format.json { render :show, status: :created, location: @task } else format.html { render :home_url } format.json { render json: @task.errors, status: :unprocessable_entity } end end end def update respond_to do |format| if @task.update(task_params) format.html { redirect_to root_url } format.json { render :home_url, status: :ok, location: @task } else format.html { render :root_url } format.json { render json: @task.errors, status: :unprocessable_entity } end end end def edit end def destroy @task.destroy respond_to do |format| format.html { redirect_to root_url } format.json { head :no_content } end end private def set_task @task = Task.find(params[:id]) end def task_params params.require(:task).permit(:deadline, :body, :project_id) end end |
路线档案:
1 2 3 4 5 6 7 | devise_for :users, :controllers => { :omniauth_callbacks =>"callbacks" } # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html root 'projects#index' resources :projects do resources :tasks end |
我的路线:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | projects#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 |
有人可以帮我澄清问题出在哪里,问题是什么?
问题出在您的
将TasksController修改为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | class TasksController < ApplicationController before_action :set_project before_action :set_task, only: [:show, :edit, :update, :destroy] before_action :authenticate_user! def index @tasks = @project.tasks end def show #makes use of set_task end def new @task = @project.tasks.new end def edit end def references respond_to do |format| if @task.valid? format.html { redirect_to root_url } format.json { render :show, status: :created, location: @task } else format.html { render :home_url } format.json { render json: @task.errors, status: :unprocessable_entity } end end end def create @task = @project.tasks.create(task_params) respond_to do |format| if @task.valid? format.html { redirect_to root_url } format.json { render :show, status: :created, location: @task } else format.html { render :home_url } format.json { render json: @task.errors, status: :unprocessable_entity } end end end def update respond_to do |format| if @task.update(task_params) format.html { redirect_to root_url } format.json { render :home_url, status: :ok, location: @task } else format.html { render :root_url } format.json { render json: @task.errors, status: :unprocessable_entity } end end end def destroy @task.destroy respond_to do |format| format.html { redirect_to root_url } format.json { head :no_content } end end private def set_project @project = current_user.projects.find(params[:project_id] end def set_task @task = @project.tasks.find(params[:id]) end def task_params params.require(:task).permit(:deadline, :body, :project_id) end end |
由于我们已经定义了
在ProjectsController #index中,您实际上不会获得
1 2 3 | def index @projects = current_user.projects unless current_user.nil? end |
我不明白你的
1 2 3 4 | def show #@project is available from load_project @tasks = @project.tasks end |
您也可以将
1 2 3 4 5 6 7 | def load_project begin @project = Project.find(params[:id]) #raises an exception if project not found rescue ActiveRecord::RecordNotFound redirect_to projects_path end end |
要了解有关拯救异常的更多信息,请参阅Ruby中的Begin,Rescue和Ensure?
有关详细信息,请参阅http://blog.8thcolor.com/en/2011/08/nested-resources-with-independent-views-in-ruby-on-rails/
如果要在projects / index.html.erb中创建新任务的表单,则应该为视图提供@task变量;尝试更改索引操作如下:
1 2 3 4 | def index @projects = current_user.projects unless current_user.nil? @task = Task.new end |
问题在于提交表单的网址。如果检查
1 2 3 4 | <%= form_for [@project, @task],url: project_tasks_path(@project) do |f| %> <%= f.input :body,class: 'form-control' %> <%= f.submit 'Add task', class: 'btn' %> <% end %> |
甚至更好,我认为你应该能够在不传递url选项的情况下做到这一点:
1 2 3 4 | <%= form_for [@project, @task] do |f| %> <%= f.input :body,class: 'form-control' %> <%= f.submit 'Add task', class: 'btn' %> <% end %> |
UPDATE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | def index project = Project.find(params[:project_id]) @projects = ProjectsViewPresenter.new(project) end # presenters/projects_view_presenter.rb class ProjectsViewPresenter attr_reader :project def initialize(project) @project = project end def tasks @tasks ||= project.tasks end def task @task ||= tasks.new end end |
您的form_for现在将是这样的:
1 2 3 4 | <%= form_for [@project.project, @project.task] do |f| %> <%= f.input :body,class: 'form-control' %> <%= f.submit 'Add task', class: 'btn' %> <% end %> |