表单提交

时间:2017-01-27 14:23:33

标签: ruby-on-rails ruby-on-rails-5 form-for strong-parameters nested-resources

我已经查看了同一错误的各种线程并尝试了人们建议的不同内容,但似乎无法想出这一点。我使用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的创建方法,但是当它提交时我得到&#34;步骤引用必须存在&#34;错误。基于其他线程,似乎这可能与强参数有关,但一切看起来都很标准。

这是来自终端的日志

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)

我几个小时都在为此烦恼,所以如果有人能说清楚,我会非常感激!

1 个答案:

答案 0 :(得分:0)

我认为您的问题不在于您的参数,而在于您构建表单的方式。通常,使用嵌套属性执行表单的方法是使用fields_for帮助程序(info here)。

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

<%= 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 %>