Добавление дополнительного поля в таблицу соединений в has_many через ассоциацию - PullRequest
2 голосов
/ 13 июня 2019

В моем приложении есть задания, которые после завершения могут быть просмотрены. Таблица просмотра предварительно заполнена предопределенными значениями. Менеджер должен установить флажки всех отзывов, которые он хочет добавить в работу.

У меня есть has_many: через ассоциацию с дополнительным столбцом, который является дополнительной ассоциацией в таблице соединений:

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

В представлении у меня есть такая форма:

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

и контроллер выглядит так:

  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>

метод создания в контроллере:

  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

1 Ответ

0 голосов
/ 14 июня 2019

Прежде всего:

  • ошибка в модели JobReview. Заменить belongs_to :job_review на belongs_to :review
  • метод job_review_params должен быть переименован в job_params, так как на самом деле это объект Job, которому вы назначаете параметры.

Когда вы назначаете reviews для job, передавая параметр review_ids, 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 через форму, поскольку она доступна в контроллере:

= 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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...