Jika saya memiliki model ActiveRecord :: Base dengan lingkup standar:
class Foo < ActiveRecord::Base
default_scope :conditions => ["bar = ?",bar]
end
Apakah ada cara untuk melakukan Foo.find
tanpa menggunakan default_scope
ketentuan? Dengan kata lain, dapatkah Anda mengganti ruang lingkup default?
Saya akan berpikir bahwa menggunakan 'default' dalam nama akan menyarankan bahwa itu bisa ditimpa, kalau tidak akan disebut sesuatu seperti global_scope
, kan?
ruby-on-rails
Gareth
sumber
sumber
Jawaban:
Jawaban singkat: Jangan gunakan
default_scope
kecuali Anda benar-benar harus. Anda mungkin akan lebih baik dengan lingkup bernama. Dengan itu, Anda dapat menggunakanwith_exclusive_scope
untuk mengganti ruang lingkup default jika perlu.Lihat pertanyaan ini untuk lebih jelasnya.
sumber
default_scope
mungkin tampak seperti ide yang bagus, tetapi kemungkinan akan menyebabkan beberapa sakit kepala selama masa aplikasi Anda.with_exclusive_scope
telah dihapus di rel 3default_scope
adalah alat yang sangat baik dan ada situasi di mana Anda bisa dengan cara lain tetapidefault_scope
itu adalah hal yang tepat untuk dilakukan. Misalnya, ketika Anda memilikiProduct
model yang memilikiinactive
bendera, atur adefault_scope { where inactive: false }
adalah hal terbaik untuk dilakukan, karena 99% atau case Anda tidak ingin menampilkan produk yang tidak aktif. Kemudian Anda tinggal memanggilunscoped
1% kasing yang tersisa, yang mungkin merupakan panel Admin.Dalam Rails 3:
sumber
def self.random; unscoped.order('rand()'); end
dihapus menghapus SEMUA sql sebelum itu, bukan hanya apa yang terdaftar di bawah default_scope. Sementara secara teknis jawaban yang benar, berhati-hatilah menggunakanunstopped
unscoped
ketika dapat langsung mengikuti model, misalnyaFoo.unscoped.blah()
ok tapi tidak pernahFoo.blah().unscoped
.Jika Anda hanya perlu mengubah urutan yang ditentukan
default_scope
, Anda dapat menggunakanreorder
metode ini .menjalankan SQL berikut:
sumber
scope :without_default_order, -> { reorder("") }
dan Anda dapat melakukan hal-hal sepertiFoo.without_default_order.order("created_at ASC")
Dalam beberapa situasi ini berbunyi lebih baik (mungkin bukan situasi yang tepat ini, tapi saya punya satu).Karena
4.1
Anda dapat menggunakanActiveRecord::QueryMethods#unscope
untuk melawan ruang lingkup default:Hal ini saat ini mungkin untuk
unscope
hal-hal seperti::where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having
.Tapi tetap tolong hindari penggunaan
default_scope
jika Anda bisa . Ini untuk kebaikanmu sendiri.sumber
Anda bisa mengganti lingkup default menggunakan
with_exclusive_scope
metode ini. Begitu:with_exclusive_scope
dokumentasisumber
Rails 3 default_scope tampaknya tidak ditimpa seperti di Rails 2.
misalnya
Di aplikasi saya, menggunakan PostgreSQL, pemesanan dalam lingkup default MENANG. Saya menghapus semua default_scope saya dan mengkodekannya secara eksplisit di mana-mana.
Pitfall Rails3!
sumber
Bar.foos.reorder(:created_at => :asc)
Dengan Rails 3+ Anda dapat menggunakan kombinasi unscoped dan menggabungkan:
sumber
User.unscoped.where(email: "[email protected]")
Pada Rails 5.1+ (dan mungkin lebih awal, tapi saya telah mengujinya berfungsi pada 5.1) dimungkinkan untuk membuka penutup kolom tertentu, yang imho adalah solusi ideal untuk menghapus
default_scope
dengan cara yang dapat digunakan di dalam lingkup bernama. Dalam kasus OPdefault_scope
,Atau
Keduanya akan menghasilkan kueri sql yang tidak menerapkan ruang lingkup asli, tetapi tidak menerapkan kondisi apa pun lainnya yang digabungkan ke dalam arel.
sumber
Ya, Anda selalu dapat menggunakan favorit waktu lama
find_by_sql
dengan kueri lengkap. Sebagai contoh: Model.find_by_sql ("SELECT * FROM model WHERE id = 123")sumber