Ruby on Rails: ActiveRecord :: NotNullViolation: SQLite3 :: ConstraintException: ограничение NOT NULL не выполнено: ошибка при попытке запустить модульные тесты - PullRequest
2 голосов
/ 05 октября 2019

Я пытаюсь запустить модульные тесты в моем приложении, и моей первоначальной ошибкой было «таблица xx не имеет столбца с именем yy», поэтому в своем файле yml я изменил поля на id. Однако теперь он выдает мне эту ошибку:

CarsControllerTest # test_should_destroy_car: ActiveRecord :: NotNullViolation: SQLite3 :: ConstraintException: сбой ограничения NOT NULL Как исправить это и запустить мои тесты?

Ответы [ 2 ]

1 голос
/ 05 октября 2019
create_table "cars_parts", force: :cascade do |t|
    t.integer "car_id"
    t.integer "part_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["car_id"], name: "index_cars_parts_on_car_id"
    t.index ["part_id"], name: "index_cars_parts_on_part_id"
  end

У вас есть ненулевое ограничение на created_at в cars_parts.

В ошибке вы можете увидеть, что created_at не может быть пустым:

SQLite3::ConstraintException: NOT NULL constraint failed: cars_parts.created_at

Итак, в вашем yml-файле вам нужно установить create_at:

one:
  car_id: 1
  part_id: 1
  created_at: Time.current
  updated_at: Time.current

two:
  car_id: 2
  part_id: 2
  created_at: Time.current
  updated_at: Time.current

РЕДАКТИРОВАТЬ:

Как отметил Себастьян, это не идеальное решение,AR должен автоматически добавлять эти временные метки.

Реальная проблема в том, что вы назвали свою модель CarParts, поэтому она не находит модель. Вам следует переименовать файл в cars_part.rb, а имя модели - в CarsPart.

Другие люди, у которых возникла эта проблема, объясняют причину, по которой модель не найдена:

https://github.com/rails/rails/issues/23316

0 голосов
/ 06 октября 2019

Когда вы используете has_and_belongs_to_many, таблица соединения не должна была создавать / updated_at отметки времени, и вам не нужна модель CarsParts (требуется только таблица, а не модель). Если вам нужна модель CarsParts, вы должны использовать has_many и has_many: посредством ассоциаций ActiveRecord обрабатывает модель соединения как фактическую модель и устанавливает временные метки

Итак, вам необходимо указать:

1- удалите временные метки из таблицы соединений и удалите модель CarsParts

или

2 - добавьте правильные ассоциации и исправьте таблицу и имя модели:

CarPart #not CarsParts
  belongs_to :car
  belongs_to :part
  self.table_name = 'cars_parts' # the actual plural would be car_parts, not cars_parts

Part
  has_many :car_parts
  has_many :cars, through: :cars_parts

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