2017-06-26 3 views
1

Ich verwende rspec zum Testen. Ich habe dieses Stück Code:Rspec: || = Operator bewertet wiederholt den Code

class Service 
    def execute 
    all_users.update_all(status: 'deactive') 
    end 

    def all_users 
    @all_users ||= User.status_active 
    end 
end 

Dann habe ich die folgenden zwei Erwartungen:

expect(service.all_users.count).to eq 10 
service.execute 
expect(service.all_users.count).to eq 0 

Beide zurückkehren true. Es bedeutet, dass das erste Mal, wenn ich all_users aufrufen, es einmal ausgewertet wird. Und beim zweiten Anruf wird all_users erneut ausgewertet, diesmal weil ich den Zustand aller Benutzer in deactive geändert habe und der gesamte aktive Benutzer null ist.

Der Operator ||= wertet den Code für die Variable nur beim ersten Mal aus. Warum wird mein Code oben erneut ausgewertet?

+0

Ist service.object_id in allen drei Fällen gleich? – Ucpuzz

Antwort

3

Ich vermute, User.all_users ist entweder ein Bereich oder eine Klassenmethode, die etwas wie where(status: 'active') tut.

In diesem Fall gibt User.all_users keine Sammlung von Modellen, sondern eine träge ausgewertete SQL-Abfrage zurück. Wenn Sie User.status_active schreiben, machen Sie tatsächlich eine neue SQL-Abfrage und erhalten die tatsächlichen Daten

4

Was Andry sagte, ist wahr; Der in @all_users gespeicherte Wert ist nicht nur ein Array oder eine Liste, es ist eine Beziehung. Wenn Sie all_users.count aufrufen, erstellt es eine DB-Abfrage, um das Ergebnis zu bestimmen.