2012-01-25 24 views
14

W oparciu o API Rails 3 różnica między metodą zakresu i klasy praktycznie nie istnieje.Scope vs Class Method in Rails 3

class Shipment < ActiveRecord::Base 
    def self.unshipped 
    where(:shipped => false) 
    end 
end 

jest taka sama jak

scope :unshipped, where(:shipped => false) 

Jednak jestem stwierdzenia, że ​​ja czasem coraz różne rezultaty ich stosowania.

Podczas gdy oba generują takie same, poprawne zapytanie SQL, zasięg nie zawsze wydaje się zwracać prawidłowe wartości po wywołaniu. Wygląda na to, że ten problem występuje tylko wtedy, gdy w metodzie nazywany jest tak samo dwukrotnie, chociaż na innej przesyłce. Za drugim razem, gdy się go nazywa, przy użyciu zakresu zwraca to samo, co za pierwszym razem. Natomiast jeśli używam metody klasy, działa poprawnie.

Czy istnieje jakieś buforowanie zapytań, które występuje podczas korzystania z zakresu?

Edit:

order.line_items.unshipped 

Linia powyżej sposób zakres jest nazywany. Zamówienia mają wiele line_items.

Metoda generate_multiple_shipments jest wywoływana dwa razy, ponieważ test tworzy zamówienie i generuje przesyłki, aby sprawdzić ich liczbę. Następnie dokonuje zmiany w zamówieniu i regeneruje przesyłki. Jednak group_by_ship_date zwraca takie same wyniki, jakie wykonał od pierwszej iteracji zamówienia.

def generate_multiple_shipments(order) 
    line_items_by_date = group_by_ship_date(order.line_items.unshipped) 

    line_items_by_date.keys.sort.map do |date| 
    shipment = clone_from_order(order) 
    shipment.ship_date = date 
    line_items_by_date[date].each { |line_item| shipment.line_items << line_item } 
    shipment 
    end 
end 

def group_by_ship_date(line_items)  
    hash = {} 
    line_items.each do |line_item| 
    hash[line_item.ship_date] ||= [] 
    hash[line_item.ship_date] << line_item 
    end 
    hash 
end 
+2

Może Pan podać przykład (fragment kodu) gdzie można sądzić kwerenda pobiera buforowane kiedy wywoływana dwukrotnie. –

+0

Dodałem więcej informacji do pierwotnego wpisu. – blim8183

+0

Sprawdzanie dziennika szyn pokazuje, czy wynik jest buforowany. – Sasha

Odpowiedz

1

Myślę, że twoje wywołanie jest nieprawidłowe. Należy dodać tak zwaną metodę zapytań do wykonania zakres, takich jak all, first, last, tj .:

order.line_items.unshipped.all 

jakie obserwowano pewne nieścisłości, zwłaszcza w RSpec, że można uniknąć poprzez dodanie metody zapytania.

Nie opublikowałeś swojego kodu testowego, więc trudno powiedzieć dokładnie, ale moim doświadczeniem było to, że po zmodyfikowaniu powiązanych rekordów, musisz wymusić przeładowanie, ponieważ pamięć podręczna zapytań nie zawsze jest wystarczająco inteligentna, aby wykryć zmianę. Przekazując true do związku, można wymusić stowarzyszenie, aby przeładować i kwerendy, aby ponownie uruchomić:

order.line_items(true).unshipped.all 
+0

Wymuszenie przeładowania skojarzenia wydaje się, że udało się. Wciąż nie do końca wiem, w jaki sposób pamięć podręczna zapytań określa, czy nastąpiła zmiana, ale przynajmniej teraz działa. Dzięki! – blim8183

+0

@ blim8183 Nie znam odpowiedzi na to, ale podejrzewam, że to mogła być kompromisowa konstrukcja. Cieszę się, że przeładowanie działało dla ciebie. –

1

Zakładając, że odwołują Rails 3.1, zakres może być dotknięte zakresu domyślnego, które mogą być zdefiniowane w danym modelu, podczas gdy metoda klasy nie będzie.