Как изменить первичный идентификатор записи в 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-идентификатор на промежуточной БД.
Не делайте этого в своей производственной БД!
Ответы
Ответ 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. Вы не можете (и действительно не должны) изменять его.