Saya sudah menjadi anak yang buruk dan menggunakan sintaks berikut di templat parsial saya untuk menetapkan nilai default untuk variabel lokal jika nilai tidak didefinisikan secara eksplisit di: hash lokal saat rendering parsial -
<% foo = default_value unless (defined? foo) %>
Ini tampaknya berfungsi dengan baik sampai saat ini, ketika (tanpa alasan saya bisa membedakan) variabel-variabel yang tidak lulus mulai berperilaku seolah-olah mereka telah didefinisikan nihil (daripada tidak terdefinisi).
Seperti yang telah ditunjukkan oleh berbagai orang yang membantu di SO, http://api.rubyonrails.org/classes/ActionView/Base.html mengatakan tidak menggunakan
defined? foo
dan bukannya digunakan
local_assigns.has_key? :foo
Saya mencoba mengubah cara saya, tetapi itu berarti mengubah banyak template.
Bisakah / haruskah saya mengisi daya ke depan dan membuat perubahan di semua templat? Apakah ada trik yang harus saya perhatikan? Seberapa rajin saya perlu menguji masing-masing?
sumber
local_assigns.fetch
benar menangani kunci genap dengan nilai nol. Ini mengembalikan default hanya jika kunci tidak disetel sama sekali.Karena
local_assigns
hash, Anda juga bisa menggunakan fetch dengan opsionaldefault_value
.Ini akan kembali
default_value
jikafoo
tidak disetel.PERINGATAN:
Hati-hati dengan
local_assigns.fetch :foo, default_value
kapandefault_value
metode, karena akan dipanggil pula untuk meneruskan hasilnyafetch
.Jika Anda
default_value
adalah sebuah metode, Anda dapat membungkusnya dalam sebuah blok:local_assigns.fetch(:foo) { default_value }
untuk mencegah panggilannya saat itu tidak diperlukan.sumber
nil
nilai dipertahankan di sini. Jika hash berisi:foo
dipetakan kenil
, makafetch
akan kembalinil
. Yaitu, setidaknya pada v1.9.3 saya. Saya tidak ingat bagaimana perilaku saya.local_assigns[:foo] || default_value
, ketika foo mengembalikan nilai falsy, yangdefault_value
akan digunakan sebagai gantinya. Biasanya masalah untuk Memoisasi@some_value ||= expensive_method
jika metode mengembalikan nilai falsy, itu akan selalu dieksekusi.foo ||= local_assigns[:foo] = local_assigns.fetch(:foo, default_value)
foo = local_assigns.fetch :foo, true
Bagaimana tentang
Ini mengatakan "gunakan
foo
jika tidak nil atau benar. Jika tidak tetapkandefault_value
ke foo"sumber
foo
merupakan boolean. Mungkin berhak memiliki nilaifalse
, dan ditimpa secaradefault_value
tidak sengaja.Saya pikir ini harus diulang di sini (dari http://api.rubyonrails.org/classes/ActionView/Base.html ):
Jika Anda perlu mengetahui apakah variabel lokal tertentu telah diberi nilai dalam panggilan render tertentu, Anda perlu menggunakan pola berikut:
Pengujian menggunakan didefinisikan? informasi utama tidak akan berfungsi. Ini adalah batasan implementasi.
sumber
Dalam kasus saya, saya menggunakan:
di parsial saya.
Saya tidak tahu kalau itu bagus tapi untuk saya tidak apa-apa
sumber
nil
sebagai panggilan parsial lokal juga.variable
boolean dan Anda perlu mengaturnyafalse
. Ini akan menggunakan nilai default daripada menggunakanfalse
nilai. GUNAKAN RISIKO ANDA SENDIRI.Aku tahu itu thread lama tapi di sini kontribusi kecil saya: saya akan menggunakan
local_assigns[:foo].presence
dalam kondisional dalam parsial. Kemudian saya aturfoo
hanya saat dibutuhkan dalam panggilan render:Lihatlah panduan resmi Rails di sini . Berlaku dari RoR 3.1.0.
sumber
local_assigns[:foo]
danlocal_assigns[:foo].presence
. Salah satu akan kembalinil
jika kunci tidak ada di hash dan nilainya jika itu ada.Saya pikir opsi yang lebih baik yang memungkinkan untuk beberapa variabel standar:
sumber
Ini adalah turunan dari jawaban Pablo. Ini memungkinkan saya untuk menetapkan default ('penuh'), dan pada akhirnya, 'mode' diatur dalam local_assigns dan variabel lokal aktual.
haml / ramping:
erb:
sumber
Lebih intuitif dan ringkas:
<% some_local = default_value unless local_assigns[:some_local] %>
sumber
:locals => {:some_local => false}
Jika Anda tidak ingin meneruskan variabel lokal ke parsial setiap kali Anda menyebutnya, lakukan ini:
Dengan cara ini Anda menghindari
undefined variable
kesalahan. Ini akan memungkinkan Anda untuk memanggil parsial Anda dengan / tanpa variabel lokal.sumber
Ruby 2.5
Erb
Itu mungkin, tetapi Anda harus mendeklarasikan nilai default Anda dalam cakupan.
VARIABEL kata untuk penggantian.
sumber
Helper dapat dibuat agar terlihat seperti ini:
Diimplementasikan seperti:
Lihat blog saya untuk detail tentang bagaimana dan mengapa.
Perhatikan bahwa solusi ini memungkinkan Anda untuk memberikan nil atau salah sebagai nilai tanpa ditimpa.
sumber