Saya menggunakan Ruby on Rails 3.2.2 dan saya ingin tahu apakah yang berikut ini adalah cara yang "tepat" / "benar" / "yakin" untuk mengganti metode penyetel untuk atribut kelas saya.
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self[:attribute_name] = value
end
Kode di atas tampaknya berfungsi seperti yang diharapkan. Namun, saya ingin tahu apakah, dengan menggunakan kode di atas, di masa depan saya akan memiliki masalah atau, setidaknya, masalah apa yang "harus saya harapkan" / "bisa terjadi" dengan Ruby on Rails . Jika itu bukan cara yang tepat untuk mengganti metode setter, apa cara yang benar?
Catatan : Jika saya menggunakan kode
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self.attribute_name = value
end
Saya mendapatkan kesalahan berikut:
SystemStackError (stack level too deep):
actionpack (3.2.2) lib/action_dispatch/middleware/reloader.rb:70
Jawaban:
================================================== ========================= Pembaruan: 19 Juli 2017
Sekarang dokumentasi Rails juga menyarankan untuk digunakan
super
seperti ini:================================================== =========================
Jawaban Asli
Jika Anda ingin menimpa metode penyetel untuk kolom tabel saat mengakses melalui model, ini adalah cara untuk melakukannya.
Lihat Mengesampingkan accessors default dalam dokumentasi Rails.
Jadi, metode pertama Anda adalah cara yang benar untuk mengesampingkan setter kolom di Model Ruby on Rails. Accessor ini sudah disediakan oleh Rails untuk mengakses kolom tabel sebagai atribut dari model. Inilah yang kami sebut pemetaan ORM ActiveRecord.
Juga perlu diingat bahwa
attr_accessible
di bagian atas model tidak ada hubungannya dengan pengakses. Ini memiliki functionlity yang sama sekali berbeda (lihat pertanyaan ini )Tetapi di Ruby murni, jika Anda memiliki aksesor yang ditentukan untuk sebuah kelas dan ingin menimpa setter, Anda harus menggunakan variabel instan seperti ini:
Ini akan lebih mudah dipahami setelah Anda tahu apa yang
attr_accessor
dilakukannya. Kodeattr_accessor :name
ini setara dengan dua metode ini (pengambil dan penyetel)Metode kedua Anda juga gagal karena akan menyebabkan loop tak terbatas saat Anda memanggil metode yang sama
attribute_name=
di dalam metode itu.sumber
attr_accessible
karena sudah tidak ada lagi, dan itu akan berfungsisuper
?super
mungkin tidak berfungsi. Tapi, sepertinya bukan itu masalahnya. Saya baru saja memeriksanya dan berfungsi untuk saya. Juga, pertanyaan ini menanyakan hal yang samawrite_attribute
. Konversi akan dilewati. Sadarilah bahwawrite_attribute
akan melewati konversi zona waktu dengan tanggal, yang hampir selalu tidak diinginkan.Gunakan
super
kata kunci:Sebaliknya, untuk menimpa pembaca:
sumber
Di rel 4
katakanlah Anda memiliki atribut umur di tabel Anda
Catatan: Untuk pendatang baru di rails 4 Anda tidak perlu menentukan attr_accessible dalam model. Sebagai gantinya Anda harus membuat daftar putih atribut Anda di tingkat pengontrol menggunakan metode izin .
sumber
Saya telah menemukan bahwa (setidaknya untuk koleksi hubungan ActiveRecord) pola berikut berfungsi:
(Ini mengambil 3 entri non-duplikat pertama dalam array yang diteruskan.)
sumber
Menggunakan
attr_writer
untuk menimpa setter attr_writer: attribute_namesumber