Есть ли способ переопределить значение идентификатора модели при создании? Что-то вроде:
Post.create(:id => 10, :title => 'Test')
было бы идеально, но явно не сработает.
ruby-on-rails
activerecord
Codebeef
источник
источник
Ответы:
id просто attr_protected, поэтому вы не можете использовать массовое присвоение для его установки. Однако при настройке вручную он просто работает:
Я не уверен, какова была первоначальная мотивация, но я делаю это при преобразовании моделей ActiveHash в ActiveRecord. ActiveHash позволяет использовать ту же семантику own_to в ActiveRecord, но вместо того, чтобы выполнять миграцию и создавать таблицу и нести накладные расходы на базу данных при каждом вызове, вы просто сохраняете свои данные в файлах yml. Внешние ключи в базе данных ссылаются на идентификаторы в памяти в yml.
ActiveHash отлично подходит для раскрывающихся списков и небольших таблиц, которые меняются нечасто и изменяются только разработчиками. Поэтому при переходе от ActiveHash к ActiveRecord проще всего сохранить все ссылки на внешние ключи одинаковыми.
источник
ActiveRecord::VERSION::STRING == "3.2.11"
здесь (с адаптером sqlite3), и все выше работает для меня.Пытаться
это должно дать вам то, что вы ищете.
источник
Вы также можете использовать что-то вроде этого:
Хотя, как указано в документации , это позволит обойти безопасность массового назначения.
источник
Для Rails 4:
Другие ответы Rails 4 у меня не работали. Многие из них, казалось, изменились при проверке с помощью консоли Rails, но когда я проверил значения в базе данных MySQL, они остались неизменными. Другие ответы работали только иногда.
По крайней мере, для MySQL присвоение
id
номера идентификатора автоинкремента ниже не работает, если вы не используетеupdate_column
. Например,Если вы перейдете
create
наnew
+, уsave
вас все равно будет эта проблема. Изменениеid
подобного вручнуюp.id = 10
также вызывает эту проблему.В общем, я бы использовал
update_column
для изменения,id
хотя это требует дополнительного запроса к базе данных, потому что он будет работать все время. Это ошибка, которая может не отображаться в вашей среде разработки, но может незаметно повредить вашу производственную базу данных, все время говоря, что она работает.источник
Post.new.update(id: 10, title: 'Test')
На самом деле получается, что делают следующие работы:
источник
validate: false
, а не простоfalse
. Однако вы по-прежнему сталкиваетесь с проблемой защищенного атрибута - есть другой способ обойти то, что я изложил в своем ответе.Как указывает Джефф, id ведет себя так, как будто он attr_protected. Чтобы предотвратить это, вам необходимо переопределить список защищенных атрибутов по умолчанию. Будьте осторожны, делая это везде, где информация об атрибутах может поступать извне. Поле id защищено по умолчанию не зря.
(Проверено с ActiveRecord 2.3.5)
источник
мы можем переопределить attributes_protected_by_default
источник
Это не кажется мне тем, что вы обычно хотели бы делать, но это работает довольно хорошо, если вам нужно заполнить таблицу фиксированным набором идентификаторов (например, при создании значений по умолчанию с помощью задачи rake), и вы хотите переопределить автоматическое увеличение (чтобы каждый раз, когда вы запускаете задачу, таблица заполнялась одними и теми же идентификаторами):
источник
Поместите эту функцию create_with_id в начало файла seed.rb, а затем используйте ее для создания вашего объекта там, где желательны явные идентификаторы.
и используйте это так
Вместо того, чтобы использовать
Foo.create({id:1,name:"My Foo",prop:"My other property"})
источник
В этом случае возникла аналогичная проблема, когда необходимо было перезаписать
id
некую настраиваемую дату:А потом :
Обратные вызовы работают нормально.
Удачи!.
источник
id
метку времени на основе Unix. Я сделал это внутриbefore_create
. Работает отлично.Для Rails 3 самый простой способ сделать это - использовать
new
сwithout_protection
уточнением, а затемsave
:Для исходных данных имеет смысл обойти проверку, которую можно сделать следующим образом:
Фактически мы добавили в ActiveRecord :: Base вспомогательный метод, который объявляется непосредственно перед выполнением файлов семян:
И сейчас:
Для Rails 4 вы должны использовать StrongParams вместо защищенных атрибутов. Если это так, вы просто сможете назначать и сохранять, не передавая никаких флагов
new
:источник
{}
добавляя атрибуты, как ответ Самуэля выше (Rails3).id
по-прежнему 10.id
было передано как 10 - так что это именно то, что должно быть. Если это не то, чего вы ожидали, не могли бы вы пояснить это на примере?В Rails 4.2.1 с Postgresql 9.5.3
Post.create(:id => 10, :title => 'Test')
работает до тех пор, пока еще нет строки с id = 10.источник
вы можете вставить идентификатор по sql:
источник