Build vs new in Rails 3

Nei documenti Rails 3, il metodo build per le associazioni è descritto come lo stesso del new metodo, ma con l’assegnazione automatica della chiave esterna. Direttamente dai documenti:

 Firm#clients.build (similar to Client.new("firm_id" => id)) 

Ho letto simili altrove.

Tuttavia, quando uso new (ad es. some_firm.clients.new senza parametri), l’associazione firm_id del nuovo client viene creata automaticamente. Sto guardando i risultati adesso nella console!

Mi sto perdendo qualcosa? I documenti sono un po ‘obsoleti (improbabile)? Qual è la differenza tra build e new ?

Stai leggendo male i documenti. some_firm.client.new sta creando un nuovo object Client dalla raccolta dei client, e quindi può impostare automaticamente firm_id su some_firm.id , mentre i documenti stanno chiamando Client.new che non ha alcuna conoscenza dell’ID dello Studio, quindi ha bisogno che il firm_id passato ad esso.

L’unica differenza tra some_firm.clients.new e some_firm.clients.build sembra essere quella build che aggiunge anche il client appena creato alla raccolta dei clients :

 henrym:~/testapp$ rails c Loading development environment (Rails 3.0.4) r:001 > (some_firm = Firm.new).save # Create and save a new Firm #=> true r:002 > some_firm.clients # No clients yet #=> [] r:003 > some_firm.clients.new # Create a new client #=> # r:004 > some_firm.clients # Still no clients #=> [] r:005 > some_firm.clients.build # Create a new client with build #=> # r:006 > some_firm.clients # New client is added to clients #=> [#] r:007 > some_firm.save #=> true r:008 > some_firm.clients # Saving firm also saves the attached client #=> [#] 

Se si sta creando un object tramite un’associazione, la build deve essere preferibile a una new poiché la build mantiene il proprio object in memoria, some_firm (in questo caso) in uno stato coerente ancor prima che qualsiasi object sia stato salvato nel database.

build è solo un alias per il new :

 alias build new 

Il codice completo può essere trovato: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb

Hai ragione, la build e le nuove funzioni hanno lo stesso effetto di impostare la chiave esterna, quando vengono chiamate attraverso un’associazione. Credo che la ragione per cui la documentazione è scritta in questo modo è di chiarire che un nuovo object Client viene istanziato, al contrario di una nuova relazione record triggers. Questo è lo stesso effetto che la chiamata di .new su una class avrebbe in Ruby. Ciò vuol dire che la documentazione sta chiarendo che chiamare build su un’associazione è la stessa cosa è creare un nuovo object (chiamando .new) e passare le chiavi esterne a quell’object. Questi comandi sono tutti equivalenti:

 Firm.first.clients.build Firm.first.clients.new Client.new(:firm_id => Firm.first.id) 

Credo che la ragione .build esiste è che Firm.first.clients.new potrebbe essere interpretato nel senso che stai creando un nuovo object relazione has_many, piuttosto che un vero client, quindi chiamare .build è un modo per chiarirlo.

build contro nuovo:

per lo più nuovi e costruiti sono uguali ma costruiscono oggetti di memoria in memoria,

per esempio.

per nuovo:

 Client.new(:firm_id=>Firm.first.id) 

Per la costruzione:

 Firm.first.clients.build 

Qui i client vengono archiviati in memoria, quando si salva l’azienda, vengono salvati anche i record associati.

Model.new

Tag.new post_id: 1 istanzia un tag con il suo set post_id .

@ model.models.new

@post.tags.build fa lo stesso E il tag istanziato sarà in @post.tags prima ancora che venga salvato.

Ciò significa che @post.save salverà sia il @post che il tag appena costruito (assumendo che sia impostato inverse_of). Questo è ottimo perché Rails convaliderà entrambi gli oggetti prima di salvare, e nessuno dei due verrà salvato se uno di essi fallisce la convalida.

models.new vs models.build

@post.tags.build e @post.tags.new sono equivalenti (almeno dal momento che Rails 3.2).