2017-01-01 5 views
6

इस कोड को समझने में मदद की ज़रूरत है, मुझे पता है कि "< <" संग्रह में शामिल है लेकिन यहां यह रिकॉर्ड सही तरीके से सहेजता है, यह कॉल किए बिना कैसे आता है । सेव विधि?रेल - बाएं शिफ्ट "<<" ऑपरेटर स्वचालित रूप से रिकॉर्ड सहेजता है

#user.rb 
has_many :saved_properties, through: :property_saves, source: :property 

#users_controller.rb 
def update 
    if @user.saved_properties << Property.find(params[:saved_property_id]) 
     render plain: "Property saved" 
end 

उत्तर

6

शायद स्रोत कोड को देखने में आपकी सहायता होगी।

def <<(*records) 
    proxy_association.concat(records) && self 
end 

rails/collection_proxy.rb at 5053d5251fb8c03e666f1f8b765464ec33e3066e · rails/rails · GitHub

def concat(*records) 
    records = records.flatten 
    if owner.new_record? 
    load_target 
    concat_records(records) 
    else 
    transaction { concat_records(records) } 
    end 
end 

rails/collection_association.rb at 5053d5251fb8c03e666f1f8b765464ec33e3066e · rails/rails · GitHub

def concat_records(records, should_raise = false) 
    result = true 

    records.each do |record| 
    raise_on_type_mismatch!(record) 
    add_to_target(record) do |rec| 
     result &&= insert_record(rec, true, should_raise) unless owner.new_record? 
    end 
    end 

    result && records 
end 

rails/collection_association.rb at 5053d5251fb8c03e666f1f8b765464ec33e3066e · rails/rails · GitHub

def insert_record(record, validate = true, raise = false) 
    set_owner_attributes(record) 
    set_inverse_instance(record) 

    if raise 
     record.save!(validate: validate) 
    else 
     record.save(validate: validate) 
    end 
    end 
: यह activerecord में << पद्धति पर आधारित खोजों की मेरी निशान है

https://github.com/rails/rails/blob/5053d5251fb8c03e666f1f8b765464ec33e3066e/activerecord/lib/active_record/associations/has_many_association.rb#L32

def insert_record(record, validate = true, raise = false) 
    ensure_not_nested 

    if record.new_record? || record.has_changes_to_save? 
     if raise 
     record.save!(validate: validate) 
     else 
     return unless record.save(validate: validate) 
     end 
    end 

    save_through_record(record) 

    record 
    end 

https://github.com/rails/rails/blob/5053d5251fb8c03e666f1f8b765464ec33e3066e/activerecord/lib/active_record/associations/has_many_through_association.rb#L38

आप देख सकते हैं, अंत में, यह save विधि कॉल करता है।

अस्वीकरण: मैं रेल सॉस कोड से परिचित नहीं हूं, लेकिन आपके पास दिलचस्प सवाल है।

6

has_manydocumentation में यह कहते हैं:

संग्रह के प्राथमिक कुंजी के लिए अपने विदेशी कुंजी सेट करके संग्रह करने के लिए एक या अधिक ऑब्जेक्ट को जोड़ता है। ध्यान दें कि यह ऑपरेशन तुरंत सहेजने के लिए प्रतीक्षा किए बिना SQL को अद्यतन करता है या मूल ऑब्जेक्ट पर कॉल करें, जब तक कि मूल ऑब्जेक्ट एक नया रिकॉर्ड न हो।

2

has_many संबंध में लिंक जानकारी लक्ष्य रिकॉर्ड में सहेजी जाती है। इसका मतलब है कि << को सेट में जोड़ने के लिए उस रिकॉर्ड को संशोधित करना होगा।

शायद सुविधा का इरादा रखते हुए, असाइनमेंट सफल होने पर असाइनमेंट करते समय ActiveRecord स्वचालित रूप से आपके लिए सहेजता है। अपवाद नए रिकॉर्ड के लिए है, उनके द्वारा रिकॉर्ड किए जा रहे रिकॉर्ड में कोई पहचानकर्ता नहीं है, जिससे देरी होनी चाहिए। वे तब सहेजे जाते हैं जब वे रिकॉर्ड के साथ जुड़े होते हैं।

यह थोड़ा उलझन में हो सकता है, शायद अप्रत्याशित, लेकिन वास्तव में वह चीज है जिसे आप 99% बार करना चाहते हैं। यदि आप नहीं चाहते हैं कि ऐसा करने के लिए आप मैन्युअल रूप से संबंध में हेरफेर करना चाहिए:

property = Property.find(params[:saved_property_id]) 
property.user = @user 
property.save! 

वह मूल रूप से बराबर लेकिन एक बहुत अधिक वर्बोज़ है।

संबंधित मुद्दे