2009-11-05 12 views

risposta

23

Mentre è bene per alcune persone a dire "RTFM" Ho piuttosto il più walk-through-ma-ancora-entirely- inutili, quando-Rails-3-viene-out-and-cambiamenti-tutto di risposta:

Come funziona in Rails 2.3 (alias "oggi")

save chiama 012.che assomiglia a questo:

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

È possibile ignorare la prima linea di questo metodo in quanto si solleva solo un errore se il record è di sola lettura (di solito non è, ma nel caso di join può essere) . Quello che ci interessa qui è la seconda e la terza riga all'interno del metodo.

La seconda linea chiama new_record? che è definita come questo:

# 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 

e la variabile @new_record è impostato quando il initialize (new chiamate initialize, e ci dà un nuovo oggetto, alcuni retroscena di Ruby-fu qui) il metodo è chiamato.

Quindi, se questo è @new_recordtrue lo chiameremo create e se è falso che chiameremo update che ci porta a quello che stai dopo, credo.

Inoltre, quando si trova un record non chiama initialize e pertanto non imposta @new_record. Se hai notato, il codice dietro new_record? era @new_record || false, il che significa che restituirà false se @new_record non è stato impostato.

Diciamo ad esempio che si desidera trovare l'ultimo record Forum, quindi si dovrebbe fare Forum.last.

  1. Questo chiama il metodo last sulla classe Forum, che eredita da ActiveRecord :: Base
  2. lastcalls il metodo della classe find.
  3. findcallsfind_last
  4. find_lastcallsfind_initial
  5. find_initialcallsfind_every
  6. find_everycallsfind_by_sql
  7. e find_by_sql chiamate instantiate

Vedrai qui che da nessuna parte lungo questa modifica è impostato @new_record e quindi qualsiasi record ottenuto da find non sarà un nuovo record.

Spero che questo ti aiuti a capire.

+0

risposta molto bella e ti penso per il tempo che ti ho dedicato per scriverlo. sono anche interessato a sapere cosa impostare @nw_record su false? eseguire una ricerca lo farebbe se estrasse un record dal database? – rip747

+0

Ho aggiornato il post con la catena di metodi di ricerca. –

+0

Esiste comunque la possibilità di modificare da soli l'attributo "new_record" –

1

Controlla il documento here di activerecord e il codice sorgente there.

+0

ho letto i documenti e il codice e non riesco a capirlo. – rip747

+0

Anche tu stai collegando al master. Probabilmente sta usando 2.3. –

2

Principalmente si basa sul metodo new_record?.
Questo metodo restituisce true se è un nuovo record e false se non lo è.

In effetti non è molto difficile.

  • Quando si ottiene un record esistente, non è nuovo. Quindi new_record? può restituire direttamente false.
  • Quando si crea un nuovo record (Model.new), new_record? restituirà true. È un nuovo record.
  • Quando salvi quel nuovo record, non è più nuovo. La variabile interna @new_record viene aggiornata. new_record? non restituirà più true.

Per vedere quando accade, andare a ActiveRecord::Base, linea 2911

self.id ||= new_id 

    @new_record = false 
    id 
    end 
+0

Stai collegando al master quando probabilmente usa 2.3. –

+0

Ciò non cambia la mia argomentazione. Ma ho comunque aggiornato il collegamento. –

Problemi correlati