2015-12-28 12 views
5

W moich modelach mam użytkowników (User) i historie (Story), z relacją: user has_many stories.Ruby on Rails: #any? zwraca nieprawidłową wartość

Zauważyłem coś dziwnego w mojej skorupie:

(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 

Jak to działa? Czy to z powodu mojego kodu, czy jest to jakiś błąd w Railsach i sposób, w jaki wysyła zapytanie do bazy danych?

+0

@sawa co masz na myśli angielskie znaki interpunkcyjne? Czy mógłbyś być bardziej precyzyjny? Oczywiście nie jestem native speakerem i czasami po prostu nie widzę, gdzie jest błąd. – Mat

+1

Dobra. Zasady są różne w różnych językach. W języku francuskim używamy spacji przed i po, gdy znak interpunkcyjny składa się z dwóch części. – Mat

+0

możliwa usterka aktywnego związku szyn? zobacz źródło http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-any-3F, która wywołuje http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method- i-empty-3F i zwraca true 'if limit_value == 0' - może być optymalizacją, aby uniknąć wielokrotnego trafiania w bazę danych? Zastanawiam się, czy zachowuje się tak samo w środowisku TEST w szynach? – house9

Odpowiedz

0

Rozwiązaniem znalazłem (dzięki @ house9) jest użycie:

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

ten sposób Rails jest zmuszony do zapytania. A narzut jest dość niski, ponieważ wykonanie kilkukrotnego zapytania wykonuje tylko raz.

Albo lepiej, jak @Jordan zasugerował, przeznaczenie:

user.stories.exists? 
+0

To spowoduje załadowanie wszystkich historii użytkownika do pamięci. Jeśli nie potrzebujesz używać informacji o historiach, po prostu użyj 'user.stories.count> 0'. Wykona prostą operację liczenia na db, zamiast wybierać wszystkie jej pola i serializować je do tablicy ruby. –

+1

Nie używaj 'count', używaj [' exists? '] (Http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F). Po to jest to. –

+0

@Jordan Jeszcze lepiej. –