2009-11-05 12 views

Odpowiedz

23

Chociaż to dobrze dla niektórych ludzi, aby powiedzieć "RTFM" I raczej więcej walk-through-ale-jeszcze-entirely- bezużyteczne, kiedy, Szyny 3-przychodzi-out-i-zmiany-wszystko odpowiedź:

Jak to działa w Rails 2.3 (aka "dzisiaj")

save wzywa create_or_update który wygląda następująco:

def create_or_update 
    raise ReadOnlyRecord if readonly? 
    result = new_record? ? create : update 
    result != false 
end 

Można zignorować pierwszą linię tej metody, jak to tylko podnosi błąd, jeśli płyta jest tylko do odczytu (zwykle nie jest, ale w przypadku złączeń może być) . Tutaj interesuje nas druga i trzecia linia metody.

Druga linia nazywa new_record? który jest zdefiniowany jako to:

# Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet; otherwise, returns false. 
    def new_record? 
    @new_record || false 
    end 

I zmienna @new_record jest ustawiony gdy initialize (new rozmowy initialize i daje nam nowy obiekt, niektóre tło Ruby-fu tutaj) metoda jest wywoływana.

Więc jeśli ten @new_record jest true będzie to nazwać create a jeśli jest to fałszywy będzie to nazwać update który prowadzi nas do tego, co jesteś po, myślę.

Ponadto, po znalezieniu rekordu nie jest wywoływany initialize i dlatego nie ustawia @new_record. Jeśli zauważyłeś, kod pod numerem new_record? był @new_record || false, co oznacza, że ​​zwróci wartość false, jeśli nie ustawiono @new_record.

Załóżmy na przykład, że chcesz znaleźć ostatni rekord Forum, aby wykonać Forum.last.

  1. To wywołuje metodę last na klasie Forum, która dziedziczy z ActiveRecord :: Base
  2. lastcalls metoda klasy find.
  3. findcallsfind_last
  4. find_lastcallsfind_initial
  5. find_initialcallsfind_every
  6. find_everycallsfind_by_sql
  7. i find_by_sql rozmowy instantiate

Zobaczysz tutaj, że nigdzie po tej zmianie nie jest ustawiony nowy rekord @new_record, a zatem każdy rekord uzyskany przez find nie będzie nowym rekordem.

Mam nadzieję, że to pomaga zrozumieć.

+0

bardzo ładna odpowiedź i myślę, że na czas, aby ją napisać. Interesuje mnie również wiedzieć, co ustawiłoby @nw_record na false? czy wykonałby to, gdyby wyciągnął rekord z bazy danych? – rip747

+0

Zaktualizowałem wpis, używając łańcucha metod wyszukiwania. –

+0

Czy mimo to należy zmodyfikować atrybut "new_record" samodzielnie –

1

Zapoznaj się z dokumentem activerecord here i kodem źródłowym there.

+0

Czytałem przez docs i kod i nie mogę owinąć się wokół niego. – rip747

+0

Ty też łączysz się z mistrzem. Prawdopodobnie używa 2.3. –

2

To principaly polega na metodzie new_record?.
Ta metoda zwraca wartość true, jeśli jest to nowy rekord, a false, jeśli nie jest.

W rzeczywistości nie jest to trudne.

  • Po otrzymaniu istniejącego rekordu nie jest nowy. Tak więc new_record? może bezpośrednio zwracać fałsz.
  • Po utworzeniu nowego rekordu (Model.new), new_record? zwróci wartość true. To nowy rekord.
  • Po zapisaniu nowego rekordu nie jest on już nowy. Zmieniono wewnętrzną zmienną @new_record. new_record? nie będzie już zwracany true.

Aby sprawdzić, kiedy zdarza się, przejdź do ActiveRecord::Base, linia 2911

self.id ||= new_id 

    @new_record = false 
    id 
    end 
+0

Podłączasz się do mistrza, kiedy prawdopodobnie używa 2.3. –

+0

To nie zmienia mojej argumentacji. Ale i tak zaktualizowałem link. –

Powiązane problemy