嵌套资源 [模型] 引用在表单提交时必须存在错误



我查看了有关同一错误的各种线程,并尝试了人们建议的不同内容,但似乎无法弄清楚这一点。我正在使用 Rails 5,但在尝试提交表单时不断收到此错误:

Step reference must exist

这是我的路线

Rails.application.routes.draw do
  resources :jobs do
    resources :steps, except: [:index], controller: 'jobs/steps'
      member do
        patch :complete
      end
  end
  get '/job/:id/next_step', to: 'jobs#next_step', as: 'next_step_jobs'
  root "pages#home"
end

我有一个作业模型和步骤模型

class Job < ActiveRecord::Base
  has_many :steps, dependent: :destroy
  accepts_nested_attributes_for :steps
  def step_completed?
    !steps.last.completed_at.blank?
  end
end
class Step < ActiveRecord::Base
  belongs_to :job, optional: true
  belongs_to :step_reference
end

这是两个控制器

class JobsController < ApplicationController
  before_action :set_job, only: [:show, :edit, :next_step, :update]
  # GET /jobs
  def index
    @dashboard = Dashboard.new
  end
  # GET /jobs/:id
  def show
  end
  # GET /jobs/new
  def new
    @job = Job.new
  end
  # GET /jobs/:id/edit
  def edit
  end
  # POST /jobs
  def create
    @job = Job.create(job_params)
    if @job.save
      # redirect to the next_step_path to ask questions
      redirect_to next_step_jobs_path(@job), flash: { success: "Job successfully added" }
    else
      redirect_to new_job_path, flash: { danger: @job.errors.full_messages.join(", ") }
    end
  end
  # PATCH /jobs/:id
  def update
    if @job.update(job_params)
      redirect_to jobs_path, flash: { success: "Job successfully updated" }
    else
      redirect_to edit_jobs_path(@job), flash: { danger: @job.errors.full_messages.join(", ") }
    end
  end
  # GET /jobs/:id/next_step
  def next_step
    # get question number from query string
    @q = params[:q]
    # create new instance of step
    @next = Next.new
    # pull the next_step object with question and answers to pass to the view
    @next_step = @next.next_step(@job, @q)
    if @next_step[:answers][0][:text].nil?
      redirect_to new_job_step_path(@job)
    else
      @next_step
    end
  end
  private
    def set_job
      @job = Job.find(params[:id])
    end
    def job_params
      params.require(:job).permit(:company, :position, :contact, :contact_email,
      :posting_url, steps_attributes: [:step_reference_id, :job_id, :completed_at, :next_step_date])
    end
end

class Jobs::StepsController < ApplicationController
  before_action :set_job
  before_action :set_step, only: [:show, :edit, :update, :complete]
  # GET /jobs/:job_id/steps/:id
  def show
  end
  # GET /jobs/:job_id/steps/new
  def new
    @step = @job.steps.new
  end
  # GET /jobs/:job_id/steps/:id/edit
  def edit
  end
  # POST /jobs/:job_id/steps/
  def create
    @step = @job.steps.create(step_params)
    if @step.save
      redirect_to jobs_path, flash: { success: "Next step successfully added." }
    else
      redirect_to jobs_path, flash: { danger: @step.errors.full_messages.join(", ") }
    end
  end
  # PATCH /jobs/:job_id/steps/:id
  def update
    if @step.update(step_params)
      redirect_to jobs_path, flash: { success: "Next step successfully updated." }
    else
      redirect_to edit_job_step_path, flash: { danger: @step.errors.full_messages.join(", ") }
    end
  end
  # PATCH /jobs/:job_id/steps/:id/complete
  def complete
    if @step.update_attribute(:completed_at, Date.today)
      redirect_to jobs_path, flash: { success: "Job step completed" }
    else
      redirect_to jobs_path, flash: { danger: @step.errors.full_messages.join(", ") }
    end
  end
  private
    def set_job
      @job = Job.find(params[:job_id])
    end
    def set_step
      @step = Step.find(params[:id])
    end
    def step_params
      params.require(:step).permit(:step_reference_id, :job_id, :completed_at, :next_step_date)
    end
end

这是我对/jobs/:job_id/steps/new 的看法

<h1 class="text-xs-center">New Step</h1>
<%= form_for @step, url: job_steps_path(@job) do |f| %>
  <div class="form-group">
    <%= f.label :next_step_date %>
    <%= f.date_field :next_step_date, class: "form-control", id: "add-next-date-field" %>
  </div>
  <%= f.submit 'Save', class: "btn btn-primary" %>
<% end %>

因此,表单应该提交给 StepsController 的创建方法,但是当它提交时,我收到"步骤引用必须存在"错误。根据其他线程,这似乎与强参数有关,但对我来说一切看起来都很标准。

这是来自终端的日志

Started POST "/jobs/1/steps" for ::1 at 2017-01-27 14:28:46 -0500
Processing by Jobs::StepsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"0hYvZArkUXj7WZw9L04ovYUSm4txz14pk8POgvJxNsdvvQ7bwQLusz5WW2u0wDGgT81k6mwDkMZLyaFIVxZW5w==", "step"=>{"next_step_date"=>"2017-01-31"}, "commit"=>"Save", "job_id"=>"1"}
  Job Load (0.2ms)  SELECT  "jobs".* FROM "jobs" WHERE "jobs"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
   (0.1ms)  begin transaction
  StepReference Load (0.1ms)  SELECT  "step_references".* FROM "step_references" WHERE "step_references"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
   (0.1ms)  commit transaction
   (0.1ms)  begin transaction
   (0.0ms)  rollback transaction
Redirected to http://localhost:3000/jobs
Completed 302 Found in 28ms (ActiveRecord: 1.0ms)

我已经为此鬼混了几个小时,所以如果有人能提供一些启示,我会非常高兴!!

我认为

你的问题不在于你的参数,而在于你构建表单的方式。通常,使用嵌套属性执行表单的方法是使用fields_for帮助程序(此处的信息)。

所以你的表单应该更像这样:

<%= form_for @job do |f| %>
  <%= f.fields_for :steps do |steps| %>
    <div class="form-group">
      <%= steps.label :next_step_date %>
      <%= steps.date_field :next_step_date, class: "form-control", id: "add-next-date-field" %>
    </div>
  <% end %>
  <%= f.submit 'Save', class: "btn btn-primary" %>
<% end %>

最新更新