2015-12-28 8 views
5

Nei miei modelli, ho utenti (User) e storie (Story), con la relazione: user has_many stories.Ruby on Rails: #any? restituisce il valore errato

ho notato qualcosa di strano nel mio guscio:

(dev) user.stories.any? 
=> true 

(dev) user.stories 
    Story Load (1.6ms) SELECT "stories".* FROM "stories" WHERE "stories"."user_id" = 703 ORDER BY created_at ASC [["user_id", 703]] 
=> [] 

(dev) user.stories.any? 
=> false 

Come funziona? Questo è dovuto al mio codice, o è un bug di qualche tipo in Rails e il modo in cui interroga il database?

+0

@sawa che cosa vuoi dire inglese punteggiatura? Potresti essere più preciso? Ovviamente non sono madrelingua e a volte semplicemente non vedo dove sia l'errore. – Mat

+1

Ok. Le regole sono diverse in tutte le lingue. In francese, utilizziamo gli spazi prima e dopo quando il segno di punteggiatura è composto da due parti. – Mat

+0

possibile difetto nella relazione attiva delle rotaie? vedi source per http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-any-3F che chiama http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method- i-empty-3F e restituisce true 'if limit_value == 0' - potrebbe essere un'ottimizzazione per evitare di colpire il database più volte? Mi chiedo se si comporta allo stesso modo in ambiente TEST rotaie? – house9

risposta

0

Una soluzione che ho trovato (grazie a @ house9) è quello di utilizzare:

user.stories.to_a.any? 
user.stories.to_a.empty? # also works with empty? 

In questo modo, Rails è costretto a fare la query. E il sovraccarico è piuttosto basso poiché fare to_a.any? più volte fa la query una sola volta.

O meglio , come suggerito @Jordan, uso:

user.stories.exists? 
+0

Questo caricherà tutte le storie utente in memoria. Se non hai bisogno di usare le informazioni sui racconti, usa 'user.stories.count> 0'. Eseguirà una semplice operazione di conteggio sul db, invece di selezionare tutti i suoi campi e serializzarli in un array di ruby. –

+1

Non usare 'count', usa [' exists? '] (Http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F). Ecco a cosa serve –

+0

@Jordan Ancora meglio. –