Сохранение модели с ассоциацией has_many не проходит проверку - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь сохранить объект в базе данных и создать ассоциации has_many, но он не проходит проверку. В настоящее время я использую Postgres на Rails 5.2.

item.rb

class Item < ApplicationRecord
  has_many :routings,     dependent: :destroy
  has_many :work_centers, through: :routings
  validates :number, presence: true, 
                     length: { maximum: 255 },
                     uniqueness: true
  ...
end

routing.rb

class Routing < ApplicationRecord
  belongs_to :item
  belongs_to :work_center
  validates :item_id, presence: true
  validates :work_center_id, presence: true
  ...
end

work_center.rb

class WorkCenter < ApplicationRecord
  has_many :routings, dependent: :destroy
  has_many :items,    through: :routings
  validates :name, presence: true, length: { maximum: 255 }, 
                   uniqueness: { case_sensitive: false }
  validates :sequence, presence: true,
                       uniqueness: true
end

items_controller.rb

def create
  @item = Item.new(item_params)
  if @item.save
    ...
  end
end

private
  def item_params
    params.require(:item).permit(:job_id, :number, :product_type, work_center_ids: [])
  end

Когда я пытаюсь создать новую Item в консоли rails, происходит сбой с ошибкой проверки:

>   Item.create!(job_id: 58, number: "6872-ryan1", work_center_ids: [3,4])
ActiveRecord::RecordInvalid: Validation failed: Routings is invalid

Однако, если я сначала создаю Item, а затем добавляю Routings, это будет успешно:

>   i = Item.create!(job_id: 58, number: "6872-ryan1")
 => #<Item id: 583, number: "6872-ryan1", product_type: nil, job_id: 58, created_at: "2019-01-10 14:28:16", updated_at: "2019-01-10 14:28:16">
>   i.work_center_ids = [3,4]
 => [3, 4]

Я пытался добавить inverse_of: к моделям:

обновлен item.rb

class Item < ApplicationRecord
  has_many :routings,     dependent: :destroy
  has_many :work_centers, through: :routings, inverse_of: :item
  ...
end

обновленный work_center.rb

class WorkCenter < ApplicationRecord
  has_many :routings, dependent: :destroy
  has_many :items,    through: :routings, inverse_of: :work_center
end

но теперь я получаю другую ошибку:

> Item.create!(job_id: 58, number: "6872-ryan2", work_center_ids: [3])
ActiveRecord::InverseOfAssociationNotFoundError: Could not find the inverse association for work_centers (:item in WorkCenter)

Отредактировано для отображения проверок в моделях

1 Ответ

0 голосов
/ 10 января 2019

Начиная с 5-й версии ROR, belongs_to ассоциация проверяется по умолчанию, поэтому вам не нужны эти строки в модели маршрутизации:

validates :item_id, presence: true
validates :work_center_id, presence: true

Если после удаления вы можете создать маршрутизацию без item_id или work_center_id, измените belongs_to_required_by_default = false на true в файлах конфигурации.

В любом случае вам следует проверить наличие связанной модели, а не ее идентификатора. В первом случае вы проверяете, присутствует ли элемент (например) с данным идентификатором в БД, а во втором случае вы просто проверяете, имеет ли столбец item_id какое-то значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...