Masalah 1
Mari pertimbangkan contoh dasarnya:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
end
Motivasi untuk menjadikan default published: true
, mungkin untuk memastikan Anda harus menjelaskan ketika ingin menampilkan posting (pribadi) yang tidak dipublikasikan. Sejauh ini baik.
2.1.1 :001 > Post.all
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't'
Ini cukup banyak yang kami harapkan. Sekarang mari kita coba:
2.1.1 :004 > Post.new
=> #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>
Dan di sana kami memiliki masalah besar pertama dengan cakupan default:
=> default_scope akan mempengaruhi inisialisasi model Anda
Dalam contoh yang baru dibuat dari model seperti itu, default_scope
akan tercermin. Jadi meskipun Anda mungkin ingin memastikan untuk tidak membuat daftar posting yang tidak diterbitkan secara kebetulan, Anda sekarang membuat yang diterbitkan secara default.
Masalah 2
Pertimbangkan contoh yang lebih rumit:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
Mari kita dapatkan posting pengguna pertama:
2.1.1 :001 > User.first.posts
Post Load (0.3ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't' AND "posts"."user_id" = ? [["user_id", 1]]
Ini terlihat seperti yang diharapkan (pastikan untuk menggulir ke kanan untuk melihat bagian tentang user_id).
Sekarang kami ingin mendapatkan daftar semua posting - termasuk tidak dipublikasikan - katakanlah untuk tampilan pengguna yang masuk. Anda akan menyadari bahwa Anda harus 'menimpa' atau 'membatalkan' efek default_scope
. Setelah google cepat, Anda mungkin akan mengetahui tentang unscoped
. Lihat apa yang terjadi selanjutnya:
2.1.1 :002 > User.first.posts.unscoped
Post Load (0.2ms) SELECT "posts".* FROM "posts"
=> Unscoped menghapus SEMUA cakupan yang mungkin biasanya berlaku untuk pilihan Anda, termasuk (tetapi tidak terbatas pada) asosiasi.
Ada beberapa cara untuk menimpa efek yang berbeda dari default_scope
. Melakukan hal yang benar menjadi rumit dengan sangat cepat dan saya berpendapat bahwa tidak menggunakan default_scope
sejak awal, akan menjadi pilihan yang lebih aman.
unscoped
bukannyadefault_scope
pada masalah # 2default_scope
adalah ketika Anda ingin sesuatu yang akan diurutkan:default_scope { order(:name) }
.Alasan lain untuk tidak menggunakan
default_scope
adalah saat Anda menghapus instance model yang memiliki hubungan 1 ke banyak dengandefault_scope
model tersebutPertimbangkan misalnya:
Memanggil
user.destroy
akan menghapus semua postingan yang adapublished
, tetapi tidak akan menghapus postingan yang adaunpublished
. Oleh karena itu database akan melempar pelanggaran kunci asing karena berisi record yang mereferensikan pengguna yang ingin Anda hapus.sumber
default_scope sering kali direkomendasikan karena terkadang salah digunakan untuk membatasi set hasil. Penggunaan default_scope yang baik adalah untuk mengurutkan set hasil.
Saya akan menjauh dari menggunakan
where
di default_scope dan lebih suka membuat ruang lingkup untuk itu.sumber
default_scope
hanya berisiorder
. Perilakuunscoped
ini sangat tidak terduga.Bagi saya ini bukan sebuah ide yang buruk tetapi harus digunakan dengan hati-hati !. Ada kasus di mana saya selalu ingin menyembunyikan catatan tertentu ketika bidang ditetapkan.
default_scope
harus sesuai dengan nilai default DB (misalnya:{ where(hidden_id: nil) }
)unscoped
metode yang akan menghindari Andadefault_scope
Sehingga akan tergantung dan kebutuhan yang sebenarnya.
sumber
Saya hanya menemukan
default_scope
berguna hanya dalam memesan beberapa parameter untuk masukasc
ataudesc
diurutkan dalam semua situasi. Kalau tidak, saya menghindarinya seperti wabahsumber