Rails 3'teki yeniliklere karşı oluşturun


125

Rails 3 belgelerinde , buildilişkilendirme yöntemi yöntemle aynı new, ancak yabancı anahtarın otomatik olarak atanmasıyla açıklanmıştır. Doğrudan belgelerden:

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

Benzerini başka yerde okudum.

Kullandığım Ancak, new(örneğin some_firm.clients.newherhangi bir parametre olmadan), yeni müşterinin firm_iddernek olduğunu otomatik olarak oluşturulur. Şu anda konsolda sonuçlara bakıyorum!

Bir şey mi kaçırıyorum? Dokümanlar biraz güncel değil mi (olası değil)? Arasındaki fark nedir buildve new?


3
Hızlı bir cevap arayan insanlar, 2. soruyu kontrol edin: "inşa", "yeni" için bir takma
addır

Yanıtlar:


208

Belgeleri biraz yanlış okuyorsunuz. some_firm.client.newYeni yaratıyor Clientmüşteriler koleksiyonundan nesne ve böylece otomatik olarak ayarlayabilirsiniz firm_idiçin some_firm.iddokümanlar aradığınız oysa Client.newhiç bir Firmanın kimliği hiçbir bilgiye sahip ihtiyacı böylece, firm_idkendisine geçirilen.

Aradaki tek fark some_firm.clients.newve some_firm.clients.buildöyle görünüyor ki build, yeni oluşturulan istemciyi de clientskoleksiyona ekliyor :

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
#=> #<Client id: nil, firm_id: 1, created_at: nil, updated_at: nil> 
r:004 > some_firm.clients           # Still no clients
#=> [] 
r:005 > some_firm.clients.build     # Create a new client with build
#=> #<Client id: nil, firm_id: 1, created_at: nil, updated_at: nil> 
r:006 > some_firm.clients           # New client is added to clients 
#=> [#<Client id: nil, firm_id: 1, created_at: nil, updated_at: nil>] 
r:007 > some_firm.save
#=> true 
r:008 > some_firm.clients           # Saving firm also saves the attached client
#=> [#<Client id: 1, firm_id: 1, created_at: "2011-02-11 00:18:47",
updated_at: "2011-02-11 00:18:47">] 

Bir ilişkilendirme yoluyla bir nesne oluşturuyorsanız, derleme bellek içi nesnenizi (bu durumda) veritabanına herhangi bir nesne kaydedilmeden önce bile tutarlı bir durumda tuttuğundan buildtercih edilmelidir .newsome_firm


8
Kullanmak some_firm.client.newistemciyi de ekler some_firm.clientsve saveon çağrısı , geçersiz some_firmolduğunu belirten bir doğrulama hatasıyla sonuçlanır client. Her iki takdirde newve buildyeni müşteri eklemek some_firmbireyin müşteri toplama, ne yok buildbunu newyapmıyor? Yoğun olduğum için özür dilerim!
ClosureCowboy

1
+1 3.0.4 ile sonucunuzu aldım. 3.0.3'e sahip biri deli olmadığımı onaylasa çok sevinirim.
ClosureCowboy

41
@henrym 3.2.6'da göründüğü gibi client.new ve clients.build koleksiyona yeni nesneyi ekledikleri için benzerdir. Benim yaptığım gibi Google'da arama yaparken buna rastlayan herkes için bir yorum eklemek istedim
hubbard

11
Rails 3.2.3
Aditya Kapoor

4
Bu cevap Rails> 3.2.13 için doğru değildir, burada 'build' sadece 'new' için bir takma addır. @ HatemMahmoud'un aşağıdaki cevabına bakın.
Andreas

91

buildsadece şunun için bir takma addır new:

alias build new

Tam kod bulunabilir: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb#L74


13
alias build newraylar itibariyle 3.2.13
fontno

7
Bu yalnızca bazı dernekler / ilişkiler için geçerlidir. Tekil dernekler, örneğin, için tamamen farklı tanımlara sahip buildve build_#{association}. Buraya ve buraya bakın .
coreyward

1
Bu hala geçerli Rails 4mi?
fatman13

1
işte hata raporu ... restoran.customers.new gibi yeni bir müşteriyi restorana eklemeden yeni bir müşteri edinmenin bir yolu olarak, kapsamlı ... restoran gibi kullanıp kullanmadığınızı öneren hata raporu. .customers.scoped.new
user3334690

11

Haklısınız, yapı ve yeni işlevler, bir ilişkilendirme aracılığıyla çağrıldıklarında yabancı anahtarı ayarlamakla aynı etkiye sahiptir. Belgelerin bu şekilde yazılmasının nedeninin, yeni bir aktif kayıt ilişkisinin aksine yeni bir İstemci nesnesinin somutlaştırıldığını açıklığa kavuşturmak olduğuna inanıyorum. Bu, Ruby'de bir sınıfta .new çağrısının yapacağı etkiyle aynıdır. Diğer bir deyişle, dokümantasyon, bir ilişkilendirmede build çağırmanın aynı şey olduğunu açıklığa kavuşturuyor, yeni bir nesne yaratmak (.new çağırmak) ve yabancı anahtarları bu nesneye geçirmek. Bu komutların tümü eşdeğerdir:

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

.Build'in var olma nedeninin Firm.first.clients.new'in gerçek bir istemci yerine yeni bir has_many ilişki nesnesi oluşturduğunuz anlamına gelecek şekilde yorumlanabileceğine inanıyorum, bu nedenle .build çağrısı bunu açıklığa kavuşturmanın bir yoludur.


Bu yüzden onlar vardır eşdeğeri. Kesinlikle göründüğü gibi. Teşekkür ederim!
ClosureCowboy

5
Bu doğru değil. İlk ikisi, Rails'in sonraki sürümlerinde eşdeğerdir (yayınlanırken öyle görünmüyorlar). ANCAK, sonuncusu, Firma.first.clients'in yeni müşteriyi içermemesi bakımından önemli bir farka sahiptir.
tybro0103

4

buildvs new:

çoğunlukla yeni ve derleme aynıdır ancak bellekte depolar nesnesi oluşturur ,

Örneğin:

Yeni:

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

İnşa etmek için:

Firm.first.clients.build

Burada müşteriler bellekte saklanır, firma kaydedilirken ilgili kayıtlar da kaydedilir.


2

Model.new

Tag.new post_id: 1post_idsetiyle birlikte bir Etiketi somutlaştıracaktır .

@ model.models.new

@post.tags.buildaynısını yapar VE somutlaştırılmış Etiket, @post.tagskaydedilmeden önce bile olacaktır .

Bu, @post.savehem @post hem de yeni oluşturulan etiketi kaydedeceği anlamına gelir (varsayarsak: ters_of ayarlanmıştır). Bu harika, çünkü Rails kaydetmeden önce her iki nesneyi de doğrulayacak ve ikisinden biri doğrulamayı geçemezse ikisi de kaydedilmeyecek.

models.new vs models.build

@post.tags.buildve @post.tags.neweşdeğerdir (en azından Rails 3.2'den beri).


buna ne dersin The only difference between some_firm.clients.new and some_firm.clients.build seems to be that build also adds the newly-created client to the clients collection:?
ア レ ッ ク ス
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.