बिल्ड 3 में नया बनाम


125

रेल 3 डॉक्स में , buildसंघों के लिए विधि के रूप में एक ही newविधि के रूप में वर्णित किया गया है, लेकिन विदेशी कुंजी के स्वचालित असाइनमेंट के साथ। डॉक्स से सीधे:

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

मैंने कहीं और इसी तरह पढ़ा है।

हालाँकि, जब मैं उपयोग करता हूं new(जैसे some_firm.clients.newबिना किसी पैरामीटर के), तो नए क्लाइंट का firm_idजुड़ाव अपने आप बन जाता है। मैं अभी कंसोल में परिणाम देख रहा हूँ!

क्या मैं कुछ भूल रहा हूँ? क्या डॉक्स आउट ऑफ़ डेट (अप्रभावित) हैं? बीच क्या अंतर है buildऔर new?


3
लोगों को एक त्वरित जवाब की तलाश में, नीचे 2 की जाँच करें: "बिल्ड" "नए" के लिए सिर्फ एक उपनाम है
ivanreese

जवाबों:


208

आप डॉक्स को थोड़ा गलत बता रहे हैं। क्लाइंट संग्रह से some_firm.client.newएक नई Clientऑब्जेक्ट बना रहा है , और इसलिए यह स्वचालित रूप से सेट कर सकता firm_idहैsome_firm.id , जबकि डॉक्स कॉल कर रहे हैं, Client.newजिसमें किसी भी फर्म की आईडी का कोई भी ज्ञान नहीं है, इसलिए इसे firm_idपारित करने की आवश्यकता है।

के बीच एकमात्र अंतर some_firm.clients.newऔर some_firm.clients.buildऐसा लगता है कि buildनव-निर्मित क्लाइंट को भी जोड़ता है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
#=> #<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">] 

यदि आप किसी एसोसिएशन के माध्यम से ऑब्जेक्ट बना रहे हैं, buildतो इसे प्राथमिकता दी जानी चाहिए newक्योंकि बिल्ड आपके इन-मेमोरी ऑब्जेक्ट को रखता है some_firm(इस मामले में) किसी भी ऑब्जेक्ट को डेटाबेस में सहेजने से पहले भी एक सुसंगत स्थिति में।


8
का उपयोग करना some_firm.client.newभी ग्राहक को जोड़ता है some_firm.clients, और कॉल saveकरना some_firmएक clientअमान्य त्रुटि का परिणाम है जो यह दर्शाता है कि अमान्य था। यदि दोनों newऔर buildनए ग्राहक को some_firmग्राहक के संग्रह में जोड़ते हैं , buildतो वह क्या करता है जो newनहीं करता है? मुझे यहाँ घने होने का अफ़सोस है!
क्लोज कॉउबॉय

1
+1 मैंने आपका परिणाम 3.0.4 के साथ प्राप्त किया। अगर 3.0.3 के साथ कोई मुझे पागल नहीं कर सकता है तो मैं पुष्टि कर सकता हूँ।
क्लोज कॉउबॉय

41
@henrym ऐसा लगता है कि 3.2.6 क्लाइंट.न्यू और क्लाइंट.बिल्ट में समान हैं, दोनों ही नए ऑब्जेक्ट को संग्रह में जोड़ते हैं। मैं उस समय आने वाले किसी भी व्यक्ति के लिए एक टिप्पणी जोड़ना चाहता था जैसे मैंने Googling किया था
हबर्ड

11
ऐसा लगता है कि रेल में उनके बीच कोई अंतर नहीं है 3.2.3
आदित्य कपूर

4
यह उत्तर रेल> 3.2.13 के लिए सही नहीं है, जहां 'बिल्ड' केवल 'नए' के ​​लिए एक उपनाम है। नीचे @ HatemMahmoud का उत्तर देखें।
एंड्रियास

91

buildके लिए सिर्फ एक उपनाम है new:

alias build new

पूर्ण कोड पाया जा सकता है: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb#L74


13
alias build newरेल 3.2.13 के रूप में
fontno

7
यह केवल कुछ संघों / संबंधों का सच है। एकवचन संघों, उदाहरण के लिए, के लिए पूरी तरह से अलग परिभाषा है buildऔर build_#{association}यहाँ और यहाँ देखें ।
1

1
क्या यह अभी भी सही है Rails 4?
fatman13

1
यहाँ बग रिपोर्ट है ... जो बताती है कि यदि आप नए तरह का उपयोग कर रहे थे। .customers.scoped.new
user3334690

11

आप सही हैं, बिल्ड और नए फ़ंक्शंस का विदेशी कुंजी सेट करने का एक ही प्रभाव है, जब उन्हें एक एसोसिएशन के माध्यम से बुलाया जाता है। मेरा मानना ​​है कि इस तरह से दस्तावेज लिखे जाने का कारण यह स्पष्ट करना है कि नए ग्राहक सक्रिय संबंध के विपरीत एक नई क्लाइंट ऑब्जेक्ट को तत्काल बनाया जा रहा है। यह एक ही प्रभाव है कि एक कक्षा में फोन करने पर रूबी में होगा। यह कहना है कि प्रलेखन स्पष्ट कर रहा है कि एक एसोसिएशन पर कॉलिंग एक ही है एक नई वस्तु (कॉलिंग .new) बना रहा है और उस ऑब्जेक्ट के लिए विदेशी कुंजी पारित कर रहा है। ये आदेश सभी समतुल्य हैं:

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

मेरा मानना ​​है कि .build मौजूद है। फर्म .first.clients.new का अर्थ यह समझा जा सकता है कि आप वास्तविक ग्राहक के बजाय एक नया has_many संबंध ऑब्जेक्ट बना रहे हैं, इसलिए कॉल करना .build यह स्पष्ट करने का एक तरीका है।


तो वे कर रहे हैं बराबर। यह निश्चित रूप से ऐसा लगता है। धन्यवाद!
क्लोज कॉउबॉय

5
यह सही नहीं है। पहले दो रेल के बाद के संस्करणों में समान हैं (ऐसा लगता है कि पोस्टिंग के समय वे नहीं थे)। लेकिन, पिछले उस फर्म में एक महत्वपूर्ण अंतर है। नया ग्राहक नहीं होगा।
tybro0103

4

buildबनाम new:

ज्यादातर नए और बिल्ड समान होते हैं लेकिन मेमोरी में स्टोर ऑब्जेक्ट का निर्माण करते हैं ,

उदाहरण के लिए:

नए के लिए:

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

निर्माण के लिए:

Firm.first.clients.build

यहां ग्राहकों को मेमोरी में संग्रहीत किया जाता है, जब फर्म को बचाते हैं, तो संबंधित रिकॉर्ड भी सहेजे जाते हैं।


2

Model.new

Tag.new post_id: 1 इसके साथ एक टैग को तुरंत बदल देगा post_id सेट के ।

@ model.models.new

@post.tags.buildएक ही है और तत्काल टैग में होगा@post.tags सहेजे जाने से पहले ।

इसका मतलब है की @post.save @post और नव निर्मित टैग (मान: inverse_of सेट है) दोनों को बचाएगा। यह बहुत अच्छा है क्योंकि रेल बचत से पहले दोनों वस्तुओं को मान्य करेगी, और यदि उनमें से एक भी सत्यापन विफल रहता है, तो न तो बचाया जाएगा।

model.new vs model.build

@post.tags.buildऔर @post.tags.newसमतुल्य हैं (कम से कम रेल 3.2 से)।


यह कैसे 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:?
ア ッ ク ア
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.