Hanya untuk memperbarui ini karena tampaknya banyak orang datang ke ini, jika Anda menggunakan Rails 4 lihat jawaban oleh Trung Lê` dan VinniVidiVicci.
Topic.where.not(forum_id:@forums.map(&:id))
Topic.where(published:true).where.not(forum_id:@forums.map(&:id))
Saya berharap ada solusi mudah yang tidak melibatkan find_by_sql
, jika tidak maka saya rasa itu harus berhasil.
Saya menemukan artikel ini yang mereferensikan ini:
Topic.find(:all, :conditions => { :forum_id => @forums.map(&:id) })
yang sama dengan
SELECT * FROM topics WHERE forum_id IN (<@forum ids>)
Saya bertanya-tanya apakah ada cara untuk melakukan NOT IN
itu, seperti:
SELECT * FROM topics WHERE forum_id NOT IN (<@forum ids>)
ruby-on-rails
rails-activerecord
Toby Joiner
sumber
sumber
Person.all(:name.not => ['bob','rick','steve'])
Jawaban:
Rails 4+:
Rel 3:
Di mana
actions
array dengan:[1,2,3,4,5]
sumber
Topic.where('id NOT IN (?)', (actions.empty? ? '', actions)
. Itu masih akan rusak pada nil, tapi saya menemukan bahwa array yang Anda lewati biasanya dihasilkan oleh filter yang akan kembali[]
paling tidak dan tidak pernah nihil. Saya sarankan memeriksa Squeel, sebuah DSL di atas Rekaman Aktif. Maka Anda bisa melakukanTopic.where{id.not_in actions}
:, nihil / kosong / atau sebaliknya..empty?
untuk.blank?
dan Anda nol-buktiFYI, Di Rails 4, Anda dapat menggunakan
not
sintaks:sumber
Anda dapat mencoba sesuatu seperti:
Anda mungkin perlu melakukannya
@forums.map(&:id).join(',')
. Saya tidak ingat apakah Rails akan argumen ke daftar CSV jika itu enumerable.Anda juga bisa melakukan ini:
sumber
Menggunakan Arel:
atau, jika disukai:
dan karena rel 4 pada:
Harap perhatikan bahwa pada akhirnya Anda tidak ingin forum_ids menjadi daftar id, melainkan subquery, jika demikian maka Anda harus melakukan sesuatu seperti ini sebelum mendapatkan topik:
dengan cara ini Anda mendapatkan semuanya dalam satu permintaan: sesuatu seperti:
Perhatikan juga bahwa pada akhirnya Anda tidak ingin melakukan ini, melainkan bergabung - apa yang mungkin lebih efisien.
sumber
EXPLAIN
!Untuk memperluas jawaban @ Trung Lê, di Rails 4 Anda dapat melakukan hal berikut:
Dan Anda bisa melangkah lebih jauh. Jika Anda perlu memfilter pertama hanya untuk Topik yang dipublikasikan dan kemudian menyaring id yang tidak Anda inginkan, Anda bisa melakukan ini:
Rails 4 membuatnya jauh lebih mudah!
sumber
Solusi yang diterima gagal jika
@forums
kosong. Untuk mengatasinya, saya harus melakukannyaAtau, jika menggunakan Rails 3+:
sumber
Sebagian besar jawaban di atas sudah cukup bagi Anda, tetapi jika Anda melakukan lebih banyak kombinasi predikat dan kompleks seperti itu periksa Squeel . Anda akan dapat melakukan sesuatu seperti:
sumber
Anda mungkin ingin melihat plugin meta_where oleh Ernie Miller. Pernyataan SQL Anda:
... dapat diekspresikan seperti ini:
Ryan Bates dari Railscasts menciptakan screencast yang bagus untuk menjelaskan MetaWhere .
Tidak yakin apakah ini yang Anda cari tetapi bagi saya, ini jelas terlihat lebih baik daripada kueri SQL yang disematkan.
sumber
Posting asli secara khusus menyebutkan menggunakan ID numerik, tapi saya datang ke sini mencari sintaks untuk melakukan NOT IN dengan array string.
ActiveRecord akan menanganinya dengan baik untuk Anda juga:
sumber
Bisakah id forum ini dikerjakan secara pragmatis? misalnya Anda dapat menemukan forum ini entah bagaimana - jika itu masalahnya Anda harus melakukan sesuatu seperti
Yang mana akan lebih efisien daripada melakukan SQL
not in
sumber
Cara ini mengoptimalkan keterbacaan, tetapi tidak seefisien dalam hal permintaan basis data:
sumber
Anda dapat menggunakan sql dalam kondisi Anda:
sumber
Membonceng jonnii:
menggunakan memetik daripada memetakan elemen
ditemukan melalui railsconf 2012 10 hal yang Anda tidak tahu rel bisa dilakukan
sumber
Ketika Anda query array kosong tambahkan "<< 0" ke array di blok where sehingga tidak mengembalikan "NULL" dan pecahkan query.
Jika tindakan bisa berupa array kosong atau kosong.
sumber
Topic.where("id NOT IN (?)", actions.presence || [0])
Berikut adalah query "tidak dalam" yang lebih kompleks, menggunakan subquery di rails 4 menggunakan squeel. Tentu saja sangat lambat dibandingkan dengan sql yang setara, tapi hei, itu berhasil.
2 metode pertama dalam ruang lingkup adalah ruang lingkup lain yang menyatakan alias cavtl1 dan tl1. << adalah operator yang tidak ada dalam squeel.
Semoga ini bisa membantu seseorang.
sumber