Подтвердить что ты не робот

Как изменить первичный идентификатор записи в Rails?

rails console
u = User.find(9)
u.id = 7 # There is no other record with id 7
u.save
=> true
User.all

Идентификатор не изменился.

Как изменить первичный идентификатор? Почему это предотвращает это действие?

Работа в Rails 3.0.7 и PostgreSQL.

EDIT: Поскольку есть веские причины не делать этого, я объясню, почему и, надеюсь, это хорошая причина.

Мы проводим тестирование юзабилити на этапе постановки, поэтому я хочу, чтобы он выглядел как Production, чтобы сделать его легким для всех. Я не хочу создавать путаницу или ошибки в процессе тестирования юзабилити, имея некоторые вещи в одном порядке на этапе постановки и в другом порядке на Production. Я только изменил один PK-идентификатор на промежуточной БД.

Не делайте этого в своей производственной БД!

4b9b3361

Ответ 1

Я не уверен, почему он предотвращает это действие, но он точно предотвращает его.

Вы можете обойти это, используя метод update_all для пользователя.

User.update_all("id = 7", "id = 9")

Хотя, если возможно, вам действительно следует избегать этого.

Ответ 2

Для меня работало:

User.find(7).update_column(:id, 9)

Ответ 3

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

Чтобы ответить на ваш вопрос:

Идентификационные столбцы защищены по умолчанию для массового присвоения и не могут быть установлены вручную. Но вы можете переопределить это поведение, указав метод:

def self.attributes_protected_by_default
  [] # ["id", ..other]
end

Это позволит вам назначить идентификатор вручную.

Ответ 4

Не могли бы вы уточнить, что такое ваш случай использования? Почему вы хотите изменить идентификатор? Что вы на самом деле пытаетесь сделать с ним?

В целом это плохая идея сделать это, и Rails не позволит вам сделать это легко, потому что это нарушит целостность ваших данных!

Здесь Почему: Когда вы используете реляционную базу данных (например, PostgreSQL) внизу, у вас будут отношения между вашими моделями, а это означает, что вы будете использовать идентификаторы модели в качестве ссылки в других связанных моделях... что означает, что если вы измените идентификатор записи, все эти ссылки на эту запись будут устаревать и повреждать вашу базу данных.

Я бы настоятельно рекомендовал снова проанализировать ваши требования и попытаться найти другой способ выполнить то, что вам нужно сделать (без изменения идентификаторов)

Ответ 5

Другой метод (хотя это не чистый Rails) заключается в создании нового столбца и заполнении его новыми идентификаторами.

Затем, используя программное обеспечение управления DB (не Rails), удалите атрибут Primary Key из столбца id, удалите его, переименуйте свой недавно добавленный столбец в "id" и дайте ему атрибуты основного ключа. (Если вы не можете сделать это непосредственно в своем программном обеспечении БД, затем установите свойства Unique, Auto-Increment и т.д.)

Вы также можете переместить столбец вперед (синтаксис MySQL):

ALTER TABLE table_name MODIFY COLUMN id int(11) FIRST;

Но есть еще одна вещь, которую я бы очень хотел сказать. Это было не так плохо, как я видел в другом месте, но люди: все хорошо и хорошо, чтобы сказать людям, что это не очень хорошая идея, но это не ответ на вопрос. Пожалуйста, воздержитесь от слова "Не делай этого", если вы уже не знаете случай использования человека.

В других форумах меня очень огорчили люди, говорящие: "Почему вы хотите это сделать?" или "Не делай этого", а затем не отвечая на вопрос. Они не дали мне оценки за то, что уже ЗНАЮ, что это не стандартная практика, и они ПРЕДЛАГАЛИ, что я еще не знал, что это не обычный случай использования.

Люди на этой странице не так уж плохи, и я не пытаюсь забрать их. Я просто предостерегаю: пожалуйста, проверьте свое поведение, прежде чем предполагать лекцию. Кто-то задал вопрос, и, хотя предупреждения могут быть хорошей идеей, вероятно, можно предположить, что у них есть ПРИЧИНА, желая получить ответ.

Конец разговора.

Ответ 6

Идентификатор, как правило, генерируется базой данных в качестве автоматически увеличивающейся PK. Вы не можете (и действительно не должны) изменять его.