Come selezionare dove ID in Array Rails ActiveRecord senza eccezioni
-
10-07-2019 - |
Domanda
Quando ho una serie di ID, come
ids = [2,3,5]
e io eseguo
Comment.find(ids)
tutto funziona bene. Ma quando esiste un ID che non esiste, ottengo un'eccezione. Ciò si verifica generalmente quando ottengo un elenco di ID che corrispondono ad alcuni filtri e che faccio qualcosa del genere
current_user.comments.find(ids)
Questa volta potrei avere un ID commento valido, che tuttavia non appartiene a un determinato Utente, quindi non viene trovato e ottengo un'eccezione.
Ho provato find (: all, ids)
, ma restituisce tutti i record.
L'unico modo in cui posso farlo ora è
current_user.comments.select { |c| ids.include?(c.id) }
Ma questa mi sembra una soluzione super inefficiente.
Esiste un modo migliore per selezionare ID nell'array senza ottenere eccezioni su record inesistenti?
Soluzione
Se si sta semplicemente evitando l'eccezione di cui si è preoccupati, il " find_all_by .. " la famiglia di funzioni funziona senza eccezioni.
Comment.find_all_by_id([2, 3, 5])
funzionerà anche se alcuni degli ID non esistono. Funziona in
user.comments.find_all_by_id(potentially_nonexistent_ids)
caso pure.
Aggiornamento: Rails 4
Comment.where(id: [2, 3, 5])
Altri suggerimenti
Aggiornamento: questa risposta è più pertinente per Rails 4.x
Fai questo:
current_user.comments.where(:id=>[123,"456","Michael Jackson"])
Il lato più forte di questo approccio è che restituisce un oggetto Relation
, al quale puoi unire più clausole .where
, .limit
clausole, ecc., che è molto utile. Consente inoltre ID inesistenti senza generare eccezioni.
La nuova sintassi di Ruby sarebbe:
current_user.comments.where(id: [123, "456", "Michael Jackson"])
Se hai bisogno di più controllo (forse devi indicare il nome della tabella) puoi anche fare quanto segue:
Model.joins(:another_model_table_name)
.where('another_model_table_name.id IN (?)', your_id_array)
Ora i metodi .find e .find_by_id sono deprecati nelle rotaie 4. Quindi invece possiamo usare di seguito:
Comment.where(id: [2, 3, 5])
Funzionerà anche se alcuni degli ID non esistono. Funziona in
user.comments.where(id: avoided_ids_array)
Anche per escludere gli ID
Comment.where.not(id: [2, 3, 5])
Per evitare che le eccezioni uccidano la tua app, dovresti cogliere tali eccezioni e trattarle come desideri, definendo il comportamento per la tua app in quelle situazioni in cui l'ID non viene trovato.
begin
current_user.comments.find(ids)
rescue
#do something in case of exception found
end
Ecco maggiori informazioni sulle eccezioni in ruby.
Puoi anche usarlo in named_scope se vuoi mettere altre condizioni
ad esempio include qualche altro modello:
named_scope 'get_by_ids', lambda {| ids | {: include = > [: commenti],: condizioni = > [" commenti.id IN (?) " ;, ids]}}