Rails 4.2.5
, Mongoid 5.1.0
Query aggregata condizionale MongoDB su una relazione HABTM (Mongoid, RoR)?
ho tre modelli - Mailbox
, Communication
, e Message
.
mailbox.rb
class Mailbox
include Mongoid::Document
belongs_to :user
has_many :communications
end
communication.rb
class Communication
include Mongoid::Document
include Mongoid::Timestamps
include AASM
belongs_to :mailbox
has_and_belongs_to_many :messages, autosave: true
field :read_at, type: DateTime
field :box, type: String
field :touched_at, type: DateTime
field :import_thread_id, type: Integer
scope :inbox, -> { where(:box => 'inbox') }
end
message.rb
class Message
include Mongoid::Document
include Mongoid::Timestamps
attr_accessor :communication_id
has_and_belongs_to_many :communications, autosave: true
belongs_to :from_user, class_name: 'User'
belongs_to :to_user, class_name: 'User'
field :subject, type: String
field :body, type: String
field :sent_at, type: DateTime
end
sto usando la gemma di autenticazione devise
, che dà accesso alla current_user
aiutante, che punti a l'utente corrente registrati nel
ho costruito una query per un controller che ha soddisfatto le seguenti condizioni:. Get 's mailbox
, la cui communication
' il current_user
s vengono filtrati dal campo box
, dove box == 'inbox'
. E 'stato costruito come questo (e sta lavorando):
current_user.mailbox.communications.where(:box => 'inbox')
il mio problema arrises quando cerco di costruire su questa query. Desidero concatenare le query in modo tale da ottenere solo messages
il cui messaggio last
non proviene da current_user
. Sono a conoscenza del metodo .last, che restituisce il record più recente. Sono venuto con la seguente query, ma non riesco a capire che cosa avrebbe bisogno di essere regolato in modo da farlo funzionare:
current_user.mailbox.communications.where(:box => 'inbox').where(:messages.last.from_user => {'$ne' => current_user})
Questa interrogazione produce il seguente risultato: undefined method 'from_user' for #<Origin::Key:0x007fd2295ff6d8>
Sono attualmente in grado di realizzare questo facendo quanto segue, che so essere molto inefficiente e vuole cambiare immediatamente:
mb = current_user.mailbox.communications.inbox
comms = mb.reject {|c| c.messages.last.from_user == current_user}
desidero spostare questa logica da rubino alla query di database vero e proprio. Grazie in anticipo a chiunque mi aiuti con questo, e per favore fatemi sapere se più informazioni sono utili qui.
Non penso che ActiveRecord possa farlo per voi - la condizione basata su un aggregato (ultimo) è probabilmente troppo complessa. Potrebbe essere necessario ricorrere a SQL raw. – PJSCopeland
C'è un errore? Si scrive .where (: messages.last.from_user => {'$ ne' => current_user}) '(** la condizione è sul commento **) ma in' current_user.mailbox.communications.reject {| c | c.last.from_user == current_user} '(** la condizione è in comunicazione **) –
@PJSCopeland, mongo non è un database SQL –