Jika saya memiliki ruang lingkup dengan lambda dan butuh argumen, tergantung pada nilai argumen, saya mungkin tahu bahwa tidak akan ada kecocokan, tapi saya masih ingin mengembalikan relasi, bukan array kosong:
scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }
Apa yang saya benar-benar inginkan adalah metode "tidak ada", kebalikan dari "semua", yang mengembalikan hubungan yang masih bisa dirantai, tetapi menghasilkan kueri yang dihubung pendek.
ruby-on-rails
activerecord
relation
dzajic
sumber
sumber
Jawaban:
Sekarang ada mekanisme "benar" di Rails 4:
sumber
Model.scoped
melakukan apa yang Anda cari di rel 3.Model.none
tidak berfungsi. Anda perlu menggunakan salah satu nama model asli Anda , misalnyaUser.none
atau apa saja yang Anda miliki.Solusi yang lebih portabel yang tidak memerlukan kolom "id" dan tidak menganggap tidak akan ada baris dengan id 0:
Saya masih mencari cara yang lebih "benar".
sumber
scope :none, -> { where("false") }
Datang dengan Rel 4
Dalam Rails 4, sebuah chainable
ActiveRecord::NullRelation
akan dikembalikan dari panggilan sepertiPost.none
.Baik itu, maupun metode dirantai, akan menghasilkan permintaan ke database.
Menurut komentar:
Lihat kode sumber .
sumber
Anda dapat menambahkan ruang lingkup yang disebut "tidak ada":
Itu akan memberi Anda ActiveRecord :: Relation kosong
Anda juga bisa menambahkannya ke ActiveRecord :: Base di inisialisasi (jika Anda mau):
Banyak cara untuk mendapatkan sesuatu seperti ini, tetapi tentu saja bukan yang terbaik untuk disimpan dalam basis kode. Saya telah menggunakan ruang lingkup: tidak ada ketika refactoring dan menemukan bahwa saya perlu menjamin ActiveRecord :: Relation kosong untuk waktu yang singkat.
sumber
where('1=2')
mungkin sedikit lebih ringkasModel.none
adalah bagaimana Anda akan melakukan ini.Merupakan solusi berbahaya karena ruang lingkup Anda mungkin dirantai.
User.none.first
akan mengembalikan pengguna pertama. Lebih aman digunakan
sumber
Saya pikir saya lebih suka cara ini terlihat ke opsi lain:
Mengarah ke sesuatu seperti ini:
sumber
where(false)
tidak melakukan pekerjaan - itu meninggalkan ruang lingkup tidak berubah.limit(0)
akan ditimpa jika Anda memanggil.first
atau.last
nanti dalam rantai, karena Rails akan ditambahkanLIMIT 1
ke kueri itu.none
hubungan seperti yang disebutkan di bawah ini.Gunakan scoped:
Namun, Anda juga dapat menyederhanakan kode Anda dengan:
Jika Anda ingin hasil kosong, gunakan ini (hapus kondisi if):
sumber
Itu mungkin dan jadi itu:
http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/none
Koreksi saya jika saya salah.
sumber
Ada juga varian, tetapi semua ini meminta db
sumber
where(false)
atauwhere(nil)
hanya diabaikan.