ruby-on-rails - 通过关联在 has_many 中的连接表中添加一个额外的字段

标签 ruby-on-rails ruby

在我的应用程序中,我有一些工作可以在完成后进行审查。审查表预先填充了预定义的值。经理应该选择她想要添加到工作中的所有评论的复选框。

我有一个 has_many :through 与额外列的关联,这是连接表中的额外关联:

class Job < ApplicationRecord
  has_many :job_reviews, dependent: :destroy
  has_many :reviews, through: :job_reviews

  accepts_nested_attributes_for :job_reviews, allow_destroy: true, reject_if: :all_blank
end

class Review < ApplicationRecord
  has_many :job_reviews, dependent: :destroy
  has_many :jobs, through: :job_reviews
end

class JobReview < ApplicationRecord
  belongs_to :job
  belongs_to :review
  belongs_to :user
end

在 View 中我有这样一种形式:

  = simple_form_for @job do |f|
    = f.association :reviews, collection: Review.all, as: :check_boxes, include_hidden: false, label: false
    = f.input :user_id, input_html: {value: current_user.id}
    = f.button :submit, class: 'btn btn-success'

Controller 看起来像这样:

  def job_params
    params.require(:job).permit(:user_id, review_ids: [])
  end

当我运行代码时,这些是正在处理的参数:

<ActionController::Parameters {"user_id"=>"dfd24578-5asa-4143-b209-d13cb419af30", "review_ids"=>["453852c5-45f0-4f67-a41c-e7e50dab711a", "a1303a62-fbef-5asa-95a0-a3ffa0b7616c"]} permitted: true>

Controller 中的创建方法:

  def create   
    respond_to do |format|
      if @job.update(job_params)
        format.js
      else
        format.js { render :js=>"alert('#{@job.errors.full_messages }');" }
      end
    end
  end

这是我得到的错误:

INSERT INTO "job_reviews" ("uuid", "review_id", "job_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "uuid"  [["id", "dfd24578-5asa-42b8-807c-38be1036bcf5"], ["review_id", "a1303a62-fbef-5asa-95a0-a3ffa0b7616c"], ["job_id", "cb7eba6e-95a0-45f0-81f2-490d1c80ee07"], ["created_at", "2019-06-13 12:04:08.581557"], ["updated_at", "2019-06-13 12:04:08.581557"]]
   (0.2ms)  ROLLBACK
ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR:  null value in column "user_id" violates not-null constraint

最佳答案

首先:

  • JobReview 模型中存在错误。将 belongs_to :job_review 替换为 belongs_to :review
  • job_review_params 方法应重命名为 job_params,因为它实际上是一个您为其分配参数的 Job 对象。

当您将 reviews 分配给传递 review_ids 参数的 job 时,Rails 会尝试自动创建 job_reviews协会。它失败了,因为 Rails 无法自动计算 user_id 值并且未正确传递。

虽然您在表单中有 user_id 参数,但它是作为 job 的属性传递的。 Rails 不知道如何处理它。

解决该问题的方法之一是手动将reviews 分配给job:

job_params[:review_ids].each do |review_id|
  @job.job_reviews.build(review_id: review_id, user_id: current_user.id)
end

@job.save

在这种情况下,您不必通过表单发送 user_id,因为它在 Controller 中可用:

= simple_form_for @job do |f|
  = f.association :reviews, collection: Review.all, as: :check_boxes, include_hidden: false, label: false
  = f.button :submit, class: 'btn btn-success'

关于ruby-on-rails - 通过关联在 has_many 中的连接表中添加一个额外的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56580563/

相关文章:

ruby-on-rails - Redis::InheritedError 调用 Sidekiq worker 时

javascript - 为什么 jasmine 不运行我的任何规范?

ruby-on-rails - 尝试向 Controller .find 方法添加条件

ruby-on-rails - 无法将数组转换为字符串错误

ruby-on-rails - 为什么每次都需要定义 source 到 RVM

ruby-on-rails - Rails 唯一索引和 validates_uniqueness_of 有什么区别

ruby-on-rails - 获取无效几何图形: LinearRing failed ring test after upgrading rgeo gem

Ruby:如何将函数映射到散列

ruby-on-rails - 无法让 'rails new' 工作

ruby-on-rails - 通过迁移向列添加默认值