Клонированный объект ActiveRecord отправляет нулевой идентификатор в Postgres во время сохранения - PullRequest
1 голос
/ 13 ноября 2009

Мне нужно сохранить копию объекта ActiveRecord, поэтому я использую что-то вроде:

@original = Model.find(params[:id])
@copy = @original.clone

Однако, когда я пытаюсь сохранить это в Postgres:

PGError: ОШИБКА: нулевое значение в столбце "id" нарушает ненулевое ограничение

В консоли:

@copy.id
=> ноль

Как заставить ActiveRecord не отправлять столбец id в инструкции INSERT?

Обновление:

Проблема исчезла после того, как я сделал небольшое изменение:

@new = Model.new(params[:model])
@original = Model.find(x)
@clone = @original.clone
@new.foreign_key_id = @clone.foreign_key_id

Я заменил последнюю строку на:

@new.foreign_key_id = @original.foreign_key_id

Это изменение удалило 'id' из оператора INSERT. После успешного эксперимента с этим изменением я немедленно вернул код и попытался воспроизвести ошибку. Я не смог воспроизвести ошибку. Пятница 13, может быть?

Ответы [ 2 ]

5 голосов
/ 13 ноября 2009

Вы звоните ActiveRecord :: Base # clone , а не Object # clone. ActiveRecord :: Base # clone по сути создает новый экземпляр модели, копирует хэш атрибутов и удаляет ключ id. По сути дела, то, что предлагает Люк Франци.

Я уверен, что это проблема PostgreSQL. Потому что этот код работает с MySQL.

@clone = @original.clone
@clone.save

Ошибка, которую вы имели, может быть связана с тем, как PostgreSQL обрабатывает автоинкремент. Я не могу сказать, пытается ли ActiveRecord передать неопределенный идентификатор в операторе INSERT, когда это не должно быть, или что-то пошло не так с определением.

Я не знаю достаточно о postge, чтобы диагностировать проблему. Но я подозреваю, что корень вашей проблемы может быть в миграции, определяющей вашу таблицу.

Из любопытства, что является результатом Model.new(@original.attributes) == @original.clone?

2 голосов
/ 13 ноября 2009

Просто предположение ... но возвращает ли new_record? истину для клонированного объекта?

Может быть, лучше создать новый объект модели и установить атрибуты, равные старому, например:

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