Apakah ada cara untuk mengganti nilai id model saat membuat? Sesuatu seperti:
Post.create(:id => 10, :title => 'Test')
akan ideal, tetapi jelas tidak akan berhasil.
ruby-on-rails
activerecord
Codebeef
sumber
sumber
Jawaban:
id hanya attr_protected, itulah sebabnya Anda tidak dapat menggunakan tugas massal untuk menyetelnya. Namun, saat mengaturnya secara manual, itu hanya berfungsi:
Saya tidak yakin apa motivasi aslinya, tetapi saya melakukan ini saat mengonversi model ActiveHash ke ActiveRecord. ActiveHash memungkinkan Anda menggunakan semantik milik_to yang sama di ActiveRecord, tetapi alih-alih memiliki migrasi dan membuat tabel, dan menimbulkan overhead database pada setiap panggilan, Anda cukup menyimpan data Anda dalam file yml. Kunci asing dalam database mereferensikan id dalam memori di yml.
ActiveHash sangat bagus untuk daftar pilihan dan tabel kecil yang jarang berubah dan hanya diubah oleh pengembang. Jadi, saat beralih dari ActiveHash ke ActiveRecord, paling mudah adalah menyimpan semua referensi kunci asing yang sama.
sumber
ActiveRecord::VERSION::STRING == "3.2.11"
sini (dengan adaptor sqlite3) dan yang di atas berfungsi untuk saya.Mencoba
yang akan memberikan apa yang Anda cari.
sumber
Anda juga bisa menggunakan sesuatu seperti ini:
Meskipun seperti yang dinyatakan dalam dokumen , ini akan melewati keamanan penugasan massal.
sumber
Untuk Rails 4:
Jawaban Rails 4 lainnya tidak berhasil untuk saya. Banyak dari mereka tampak berubah saat memeriksa menggunakan Rails Console, tetapi ketika saya memeriksa nilai di database MySQL, mereka tetap tidak berubah. Jawaban lain hanya kadang-kadang berhasil.
Untuk MySQL setidaknya, menetapkan di
id
bawah nomor id penambahan otomatis tidak berfungsi kecuali Anda menggunakanupdate_column
. Sebagai contoh,Jika Anda mengubah
create
untuk menggunakannew
+,save
Anda masih akan mengalami masalah ini. Mengubahid
suka secara manualp.id = 10
juga menghasilkan masalah ini.Secara umum, saya akan menggunakan
update_column
untuk mengubahid
meskipun itu memerlukan biaya query database tambahan karena akan bekerja sepanjang waktu. Ini adalah kesalahan yang mungkin tidak muncul di lingkungan pengembangan Anda, tetapi diam-diam dapat merusak database produksi Anda sambil mengatakan bahwa itu berfungsi.sumber
Post.new.update(id: 10, title: 'Test')
Sebenarnya, melakukan hal berikut ternyata berhasil:
sumber
validate: false
, bukan hanyafalse
. Namun, Anda masih mengalami masalah atribut yang dilindungi - ada cara terpisah yang telah saya uraikan dalam jawaban saya.Seperti yang Jeff tunjukkan, id berperilaku seolah-olah dilindungi_tarik. Untuk mencegahnya, Anda perlu mengganti daftar atribut default yang dilindungi. Berhati-hatilah saat melakukan ini di mana pun sehingga informasi atribut bisa berasal dari luar. Bidang id secara default dilindungi karena suatu alasan.
(Diuji dengan ActiveRecord 2.3.5)
sumber
kita dapat mengganti atribut_protected_by_default
sumber
Ini tidak menurut saya sebagai hal yang biasanya ingin Anda lakukan, tetapi berfungsi dengan baik jika Anda perlu mengisi tabel dengan satu set id tetap (misalnya saat membuat default menggunakan tugas rake) dan Anda ingin mengganti penambahan otomatis (sehingga setiap kali Anda menjalankan tugas, tabel diisi dengan id yang sama):
sumber
Letakkan fungsi create_with_id ini di bagian atas seed.rb Anda dan kemudian gunakan untuk melakukan pembuatan objek di mana id eksplisit diinginkan.
dan gunakan seperti ini
alih-alih menggunakan
Foo.create({id:1,name:"My Foo",prop:"My other property"})
sumber
Kasus ini adalah masalah serupa yang perlu ditimpa
id
dengan jenis tanggal khusus:Lalu :
Callback berfungsi dengan baik.
Semoga berhasil!.
sumber
id
berdasarkan cap waktu Unix. Saya telah melakukan itu di dalambefore_create
. Bekerja dengan baik.Untuk Rails 3, cara paling sederhana untuk melakukan ini adalah dengan menggunakan
new
denganwithout_protection
perbaikan, dan kemudiansave
:Untuk data seed, mungkin masuk akal untuk melewati validasi yang dapat Anda lakukan seperti ini:
Kami sebenarnya telah menambahkan metode helper ke ActiveRecord :: Base yang dideklarasikan segera sebelum mengeksekusi file seed:
Dan sekarang:
Untuk Rails 4, Anda harus menggunakan StrongParams alih-alih atribut yang dilindungi. Jika demikian, Anda dapat menetapkan dan menyimpan tanpa mengirimkan tanda apa pun ke
new
:sumber
{}
seperti jawaban Samuel di atas (Rails3).id
masih 10.id
diteruskan sebagai 10 - jadi memang seharusnya begitu. Jika bukan itu yang Anda harapkan, dapatkah Anda menjelaskan dengan sebuah contoh?Di Rails 4.2.1 dengan Postgresql 9.5.3,
Post.create(:id => 10, :title => 'Test')
berfungsi selama belum ada baris dengan id = 10.sumber
Anda dapat memasukkan id dengan sql:
sumber