【问题标题】:Form won't save, and no validation errors are showing on redirect. Rails 5表单不会保存,重定向时不会显示验证错误。导轨 5
【发布时间】:2025-12-11 17:20:08
【问题描述】:

我的工作申请表单对象拒绝插入数据库,即使参数正确且错误日志中没有附加任何错误。我有一个用户模型、工作模型和 job_application 模型。用户模型无法将 job_applications 保存到作业模型。如何正确设置要插入的表单而不会失败?

控制台错误

Started POST "/job_applications" for 127.0.0.1 at 2018-02-05 16:02:44 -0500
Processing by JobApplicationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"CEUd0b1IiA1iNUJ06BIycpiECrz2Q8W9Ol0Y/BDUC1ctWKjAn5/EoW8s157NAGiKFH+CZ4bZBzWAVRJvleyLSw==", "job_application"=>{"job_id"=>"1", "user_first_name"=>"James", "user_last_name"=>"Goober", "user_contact_time"=>"PM", "user_resume_link"=>"4"}, "commit"=>"Submit Application"}
  User Load (2.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.0ms)  BEGIN
  Job Load (7.0ms)  SELECT  "jobs".* FROM "jobs" WHERE "jobs"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.0ms)  ROLLBACK
  Rendering job_applications/new.html.erb within layouts/application
  Resume Load (3.0ms)  SELECT "resumes".* FROM "resumes" WHERE "resumes"."user_id" = $1 ORDER BY "resumes"."title" ASC  [["user_id", 1]]
  Rendered job_applications/_form.html.erb (792.8ms)

工作申请_form部分

<%= simple_form_for([@job_application]) do |f| %>
    <%= f.hidden_field :job_id %>
    <%= f.error_notification %>

    <div class="form-group">
      <div class="col-4">
        <label for="user-first-name">First Name</label>
        <%= f.input :user_first_name, class: 'form-control', required: true, label: false %>
      </div>
    </div>
    <div class="form-group">
      <div class="col-4">
        <label for="user-last-name">Last Name</label>
        <%= f.input :user_last_name, class: 'form-control', required: true, label: false %>
      </div>
    </div>
    <div class="form-group">
      <div class="col-3">
        <label for="user-contact-time">Contact Time</label>
        <%= f.input :user_contact_time, collection: %w(AM PM), class: 'form-control', required: true, label: false, prompt: 'Daytime or Evening' %>
      </div>
    </div>
    <div class="form-group">
      <div class="col-4">
        <% if user_signed_in? %>
          <label for="user-resume-link"><%= fa_icon 'clone' %> Resume Repository</label>
        <%= f.input :user_resume_link, collection: current_user.resumes.order(:title), prompt: "Select your Resume", label: false %>
        <% end %>
      </div>
    </div>
    <div class="form-group">
      <div class="col-4">
        <%= f.button :submit, 'Submit Application', class: 'btn btn-blue form-control' %>
      </div>
    </div>
  <% end %>

job_application.rb

class JobApplication < ApplicationRecord
  belongs_to :employer
  belongs_to :user
  belongs_to :job
  delegate :resume, to: :user
  validates :user_first_name, presence: true, uniqueness: false, length: {maximum: 50}, format: {with: /\A[a-zA-Z]+(?: [a-zA-Z]+)?\z/}
  validates :user_last_name, presence: true, uniqueness: false, length: {maximum: 50}, format: {with: /\A[a-zA-Z]+(?: [a-zA-Z]+)?\z/}
  validates :user_resume_link, presence: true
  validates :user_contact_time, presence: true
end

job.rb

class Job < ApplicationRecord
has_many :job_applications, dependent: destory
# accepts_nested_attributes_for :job_applications, :reject_if => :all_blank, :allow_destroy => true
end

job_applications_controller

class JobApplicationsController < ApplicationController
  before_action :set_job_application, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, only: [:create, :new, :update, :destroy, :edit]

  # GET /job_applications/1
  # GET /job_applications/1.json
  def show
  end

  # GET /job_applications/new
  def new
    @job_application = JobApplication.new
  end

  # GET /job_applications/1/edit
  def edit
  end

  # POST /job_applications
  # POST /job_applications.json
  def create
    @job_application = current_user.job_applications.build(job_application_params)

    respond_to do |format|
      if @job_application.save
        format.html { redirect_to @job_application, notice: 'Job application was successfully created.' }
        format.json { render :show, status: :created, location: @job_application }
      else
        format.html { render :new }
        format.json { render json: @job_application.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /job_applications/1
  # PATCH/PUT /job_applications/1.json
  def update
    respond_to do |format|
      if @job_application.update(job_application_params)
        format.html { redirect_to @job_application, notice: 'Job application was successfully updated.' }
        format.json { render :show, status: :ok, location: @job_application }
      else
        format.html { render :edit }
        format.json { render json: @job_application.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /job_applications/1
  # DELETE /job_applications/1.json
  def destroy
    @job_application.destroy
    respond_to do |format|
      format.html { redirect_to job_applications_url, notice: 'Job application was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_job_application
      @job_application = JobApplication.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def job_application_params
      params.require(:job_application).permit(:user_first_name, :user_last_name, :user_contact_time, :user_resume_link, :employer_id, :job_id, resumes_attributes: [:id, :title, :_destroy])
    end
end

用户.rb

class User < ApplicationRecord
has_many :job_applications, dependent: :destroy
  has_many :jobs, :through => :job_applications
end

【问题讨论】:

  • 您在 Job 模型dependent: destory中存在拼写错误@
  • 日志中的 "ROLLBACK" 向我建议 @job_application 的验证错误。尝试在 def create 操作中暂时使用 @job_application.save! 而不是 @job_application.save。确定问题后,修复相应的验证码,然后确保恢复到.save
  • 您能确认您的def job_application_params 是正确的吗?您有很多用户/简历字段......但是......它们是工作申请表上的实际列,还是您试图将它们融入关系? (因为这不起作用,您需要适当的嵌套字段/属性)。你能给我们你得到的实际错误信息吗? (您能向我们展示更多控制台输出吗?)当您尝试通过控制台创建一个时会发生什么?你还试过什么?等:)
  • id=1 的工作是否属于=1 的用户?由于before_action,看起来控制器正在回滚
  • 这是一个不正确的关系模型导致了错误。我是通过使用 Jay-Ar Polidario 的方法发现的。节省!表明雇主被无缘无故添加。

标签: ruby-on-rails ruby activerecord simple-form


【解决方案1】:

您确定您的表单会生成类似的输入

<input type="text" name="job_application[user-first-name]">

不是那样

<input type="text" name="user-first-name">

在第二种情况下,您需要将表单参数重写为

   def job_application_params
      params.permit(:user_first_name, :user_last_name, :user_contact_time, :user_resume_link, :employer_id, :job_id, resumes_attributes: [:id, :title, :_destroy])
    end

【讨论】:

    【解决方案2】:

    用户模型、作业模型和应用程序模型之间的关系设置不正确。 job_application 属于用户,但工作本身属于雇主。 job_application 不属于雇主。但是,它仍然可以通过作业本身访问它。

    job_application.rb

    class JobApplication < ApplicationRecord
      # belongs_to :employer removing this line, eliminated the error.
      belongs_to :user
      belongs_to :job
      delegate :resume, to: :user
      validates :user_first_name, presence: true, uniqueness: false, length: {maximum: 50}, format: {with: /\A[a-zA-Z]+(?: [a-zA-Z]+)?\z/}
      validates :user_last_name, presence: true, uniqueness: false, length: {maximum: 50}, format: {with: /\A[a-zA-Z]+(?: [a-zA-Z]+)?\z/}
      validates :user_resume_link, presence: true
      validates :user_contact_time, presence: true
    end
    

    【讨论】: