Saya ingin membuat salinan catatan activerecord, mengubah satu bidang dalam proses (selain id ). Apa cara paling sederhana untuk mencapai ini?
Saya menyadari bahwa saya dapat membuat catatan baru, dan kemudian mengulangi masing-masing bidang menyalin data bidang demi bidang - tetapi saya pikir pasti ada cara yang lebih mudah untuk melakukan ini ...
seperti:
@newrecord=Record.copy(:id) *perhaps?*
q = p.clone
, dan kemudianp == q
, sayatrue
kembali. Di sisi lain, jika saya gunakanq = p.dup
, sayafalse
kembali ketika membandingkannya.new?
metode ini tidak berfungsi.Bergantung pada kebutuhan dan gaya pemrograman Anda, Anda juga dapat menggunakan kombinasi metode baru kelas dan penggabungan. Karena tidak ada contoh sederhana yang lebih baik , misalkan Anda memiliki tugas yang dijadwalkan untuk tanggal tertentu dan Anda ingin menduplikasinya ke tanggal lain. Atribut sebenarnya dari tugas tidak penting, jadi:
akan membuat tugas baru dengan
:id => nil
,:scheduled_on => some_new_date
, dan semua atribut lainnya sama dengan tugas aslinya. Dengan menggunakan Task.new, Anda harus memanggil save secara eksplisit, jadi jika Anda ingin menyimpannya secara otomatis, ubah Task.new menjadi Task.create.Perdamaian.
sumber
WARNING: Can't mass-assign protected attributes: id, due_date, created_at, updated_at
kembaliAnda mungkin juga menyukai permata Amoeba untuk ActiveRecord 3.2.
Dalam kasus Anda, Anda mungkin ingin menggunakan
nullify
,regex
atauprefix
opsi yang tersedia di DSL konfigurasi.Ini mendukung duplikasi rekursif mudah dan otomatis
has_one
,has_many
danhas_and_belongs_to_many
asosiasi, preprocessing lapangan dan DSL konfigurasi yang sangat fleksibel dan kuat yang dapat diterapkan baik untuk model dan on the fly.pastikan untuk memeriksa Dokumentasi Amuba tetapi penggunaannya cukup mudah ...
hanya
atau tambahkan
ke Gemfile Anda
kemudian tambahkan blok amuba ke model Anda dan jalankan
dup
metode seperti biasaAnda juga dapat mengontrol bidang mana yang disalin dengan berbagai cara, tetapi misalnya, jika Anda ingin mencegah komentar agar tidak digandakan tetapi Anda ingin mempertahankan tag yang sama, Anda bisa melakukan sesuatu seperti ini:
Anda juga bisa preprocess bidang untuk membantu menunjukkan keunikan dengan awalan dan sufiks serta regex. Selain itu, ada juga banyak opsi sehingga Anda dapat menulis dengan gaya yang paling mudah dibaca untuk tujuan Anda:
Menyalin asosiasi secara rekursif itu mudah, cukup aktifkan amuba pada model anak juga
Konfigurasi DSL memiliki lebih banyak opsi, jadi pastikan untuk memeriksa dokumentasi.
Nikmati! :)
sumber
.amoeba_dup
, bukan hanya.dup
. Saya mencoba menjalankan kode ini, tetapi tidak berfungsi di sini.Gunakan ActiveRecord :: Base # dup jika Anda tidak ingin menyalin id
sumber
.clone
Saya biasanya hanya menyalin atribut, mengubah apa pun yang perlu saya ubah:
sumber
unknown attribute
kesalahan dengan satu kolom karena ada kolom yang ada karena hubungan has_many. Apakah ada jalan keluarnya?User.create(old_user.attributes.merge({ login: "newlogin", id: nil }))
. Ini akan menghemat pengguna baru dengan id unik yang benar.Jika Anda membutuhkan salinan yang dalam dengan asosiasi, saya sarankan permata deep_cloneable .
sumber
Di Rails 5 Anda cukup membuat objek duplikat atau merekam seperti ini.
sumber
Cara yang mudah adalah:
Atau
sumber
Berikut adalah contoh
#dup
metode ActiveRecord yang mengesampingkan untuk mengkustomisasi duplikasi instance dan juga menyertakan duplikasi relasi:Catatan: metode ini tidak memerlukan permata eksternal tetapi membutuhkan versi ActiveRecord yang lebih baru dengan
#dup
metode yang diterapkansumber
Anda juga dapat memeriksa permata act_as_inheritable .
"Acts As Inheritable adalah Ruby Gem yang secara khusus ditulis untuk model Rails / ActiveRecord. Ini dimaksudkan untuk digunakan dengan Self-Referential Association , atau dengan model yang memiliki orang tua yang memiliki atribut bawaan. Ini akan memungkinkan Anda mewarisi atribut apa pun atau hubungan dari model induk. "
Dengan menambahkan
acts_as_inheritable
ke model Anda, Anda akan memiliki akses ke metode ini:inherit_attributes
inherit_relations
Semoga ini bisa membantu Anda.
sumber
Karena mungkin ada lebih banyak logika, ketika menduplikasi model, saya akan menyarankan untuk membuat kelas baru, di mana Anda menangani semua logika yang diperlukan. Untuk memudahkannya, ada permata yang bisa membantu: clowne
Sesuai contoh dokumentasi mereka, untuk model Pengguna:
Anda membuat kelas cloner Anda:
dan kemudian menggunakannya:
Contoh disalin dari proyek, tetapi akan memberikan visi yang jelas tentang apa yang dapat Anda capai.
Untuk catatan cepat dan sederhana saya akan pergi dengan:
Model.new(Model.last.attributes.reject {|k,_v| k.to_s == 'id'}
sumber