我有以下的ActiveRecord型號:如何查找與給定條件無關的記錄? (ActiveRecord的/ PostgreSQL的)
class User < ApplicationRecord
has_many :user_alert_archives
end
class UserAlertArchive < ApplicationRecord
belongs_to :user
belongs_to :alert
end
class Alert < ApplicationRecord
has_many :user_alert_archives
end
當用戶歸檔指定警報,一個UserAlertArchive一條記錄被與該用戶的ID和警報ID創建。爲用戶的歸檔警報運行查詢是相當簡單的。
Alert.joins(:user_alert_archives).where(user_alert_archives: {user_id: current_user.id})
它正在查詢與那種情況相反的情況,我在麻煩纏身時遇到了麻煩。如何對不要的UserAlertArchive與當前用戶的ID相關聯的警報記錄進行高效查詢?
- 編輯 -
這是一個有點難以解釋,但這是我已經能夠得到想要的結果的唯一途徑:
archived_ids = Alert.joins(:user_alert_archives).where(user_alert_archives: {user_id: current_user.id}).pluck(:id)
Alert.where.not(id: archived_ids)
這在技術上的作品,但它拉所有存檔警報的ID,對於有成千上萬個用戶的用戶而言,這些警報相當緩慢。如果可能的話,我希望能夠在單個查詢中完成它。
我不認爲你需要加入才能得到你想要的東西。如果你將這些調用結合起來,它只會運行一個查詢。 Alert.where.not(id:current_user.user_alert_archives.select(:id)) –
好吧,現在我覺得很荒謬。這確實是一個毫無意義的加入。在我們的產品代碼中發現警報稍微複雜一點,我放棄了大腦放屁,然後在這裏發佈。但感謝您指出ActiveRecord會自動將它結合到子查詢中。我沒有意識到它足夠聰明,可以自己做一個「不在」。 – Haronious