2012-07-14 14 views
17

पर खाली रिकॉर्ड्स को सहेजने से कैसे बचें, मैं AddressBook संबंध के लिए nested_form मणि का उपयोग कर रहा हूं। मैंनेस्टेड रेल फॉर्म

जरूरत है एक मौजूदा Addr का मूल्य बाहर उपयोगकर्ता कारतूस, मुझे लगता है कि Addr बल्कि एक खाली value

class Person < ActiveRecord::Base 
    has_many :addrs, dependent: :destroy 
    attr_accessible :name, :addrs_attributes 
    accepts_nested_attributes_for :addrs, reject_if: :addr_blank, allow_destroy: true 

    def addr_blank(a) 
    valid? && a[:id].blank? && a[:value].blank? 
    end 

class Addr < ActiveRecord::Base 
    belongs_to :person 
    attr_accessible :kind, :label, :value, :person_id 

मेरे :reject_if विधि के साथ बचत की तुलना में अच्छी तरह से काम करता है को नष्ट करना चाहते, लेकिन यह मुझे सब कुछ नहीं देता है जब

  1. valid?
  2. a[:id].blank? से बचा जाता है को अस्वीकृत कर दिया सत्यापन के माध्यम से चारों ओर मेरी खाली addrs रहता है जब उपयोगकर्ता कारतूस बाहर और मौजूदा रिकॉर्ड

अब, उपयोगकर्ता को पर रिक्त करते समय मौजूदा Addr को हटाने (बजाय सहेजने) की आवश्यकता है। साथ ही, मैं एक विश्वसनीय API के माध्यम से व्यक्तियों और जोड़ों को उजागर कर रहा हूं।

  1. पोस्ट प्रक्रिया जादुई _destroy=1 परम जोड़ने के लिए params हैश: मैं दो संभावित विकल्प देखें। IOW, हटाएं बटन दबाए रखने की उपयोगकर्ता गतिविधि का अनुकरण करें।
  2. Addr मॉडल के अंदर इसे Encapsulate करें कि एक खाली value के साथ एक अद्यतन प्रभावी ढंग से एक हटा माना जाता है।

सलाह यहाँ के आधार पर मैं इसे कैसे लागू किया है:

people_controller.rb

def update 
    @person = Person.find(params[:id]) 
    @person.destroy_blank_addrs(params[:person]) 
    respond_to do |format| 
    ... 

person.rb

def destroy_blank_addrs(person_params) 
    if valid? && person_params[:addrs_attributes] 
    person_params[:addrs_attributes].each do |addr_params_array| 
     addr_params= addr_params_array[1] 
     addr_params[:_destroy] = '1' if !addr_params[:id].blank? && addr_params[:value].blank? 
    end 
    end 
end 
+0

, विकल्प 1. का उपयोग आप की तरह "यदि एक्स फ़ील्ड का मान खाली है तो अभिलेख को नष्ट" "जादू" नहीं करना चाहती। – Zabba

+0

मैंने आपके द्वारा सुझाए गए समाधान के साथ प्रश्न अपडेट किया। –

+0

@ ज़ब्बा, मैं 18 महीने बाद इस कोड को दोबारा कर रहा हूं और आप सही थे। मूल्य को "जादुई" 'नष्ट_blank_addrs' के रूप में खाली करने का मेरा विचार मस्तिष्क-मृत था। मैं यह भी मानता हूं कि 'पैराम्स' सरणी को सीधे संशोधित करने वाले किसी भी समाधान में बुरा अभ्यास है। कोई भी पोस्ट-प्रोसेसिंग 'assign_attributes' के बाद की जानी चाहिए लेकिन' save' –

उत्तर

5

एक तीसरा विकल्प होगा Perso पर before_save कॉलबैक जोड़ने के लिए n जो रिक्त सभी पते को हटा देगा। इस विचार में कुछ योग्यता है, लेकिन शायद मैं इसके साथ नहीं जाऊंगा।

आपके द्वारा पेश किए जाने वाले दो विकल्पों में से, मैं पैरा-प्रोसेसिंग पैराम के साथ नहीं जाऊंगा। यह काम करेगा, लेकिन यह बहुत अधिक काम है। इसके अलावा, नियंत्रक कोड के लिए थोड़ा गड़बड़ हो जाएगा और मैं एक बहुत पतला नियंत्रक में एक दृढ़ आस्तिक हूँ।

मेरे सिर में सबसे आसान विकल्प, सहेजने के बाद रिक्त पते को हटाना है। आप Person#remove_blank_addresses() जोड़ सकते हैं और फिर इसे सफल सहेजने पर कॉल कर सकते हैं। आपको पैराम में पास करने की आवश्यकता नहीं है - यह केवल पते को फिर से भर सकता है और रिक्त लोगों को हटा सकता है। इसे खाली पतों को बनाने और फिर उन्हें नष्ट करने का नुकसान होता है, लेकिन आपको वैसे भी लोगों को अद्यतन करने के लिए इसकी आवश्यकता होगी।

अगर हम सबसे स्वच्छ समाधान (मेरी राय में) के बारे में बात कर रहे हैं, तो मैं एक तीसरी कक्षा पेश करूंगा जो कि सभी तर्कों को संभालेगा और नियंत्रक इसे प्रतिनिधि करेगा। नियंत्रक अलगाव में परीक्षण करने के लिए काफी आसान होगा और फिर आप एक मॉडल स्पेक लिख सकते हैं जो सभी नट-किरकिरा विवरणों की जांच करता है। यह थोड़ा और काम है और मैं अभी एक अच्छा नाम नहीं सोच सकता (PersonUpdater?), लेकिन यह सोचने के लायक विचार हो सकता है।

+1

विचारशील प्रतिक्रिया के लिए धन्यवाद, स्टीफन। एक तीसरी कक्षा सबसे साफ समाधान है, लेकिन बहुत अधिक प्रयास है। कुछ एसिंक प्रक्रिया (यहां तक ​​कि केवल एक पल के लिए) के लिए उपलब्ध डीबी में रिकॉर्ड डालने का विचार गलत लगता है। एक और विचार जेएस में सामने के अंत में इसे प्रबंधित करना है। ब्लैंकिंग डिलीट बटन दबाए जाने का एक और तरीका है। फिर ब्लैंकिंग इसे मेरे आरईएसटी एपीआई में कभी नहीं बनाता है। –

+0

उस स्थिति में, मेरे पास यह कोड नियंत्रक में होगा। यह परीक्षण करने के लिए थोड़ा सा कठिन है और किसी भी तरह से मेरे विश्वास में गन्दा दिखता है कि नियंत्रक में क्या होना चाहिए, लेकिन यह आपके मामले में सबसे साफ समाधान होना चाहिए। –

+0

धन्यवाद, मैं नियंत्रक दृष्टिकोण के साथ गया क्योंकि मुझे लगा कि यह आसान था और यह मेरे एपीआई में कार्यक्षमता जोड़ता है जहां उपभोक्ता मूल्य को खाली करके एडर्स को हटा सकते हैं। यदि आप अपना उत्तर अपडेट करते हैं, तो मैं स्वीकार करूंगा। –

14
accepts_nested_attributes_for :addrs, 
    allow_destroy: true, 
    :reject_if => proc { |att| att[:name].blank? && attr[:description].blank? } 
8
accepts_nested_attributes_for :addrs, 
    allow_destroy: true, 
    reject_if: -> { |attr| [name, description].any? &:blank? } 
+0

बहुत संक्षिप्त देखें। मैं एक 'वैध' परीक्षण शामिल करता हूं ताकि उपयोगकर्ता को मान्यताओं को हल करने तक पंक्तियों को खारिज नहीं किया जा सके। –

1
accepts_nested_attributes_for :addrs, 
    allow_destroy: true, 
    reject_if: :all_blank 
दो के
+0

आपको किसी विधि को इंगित करने वाली प्रक्रिया या प्रतीक निर्दिष्ट करने की अनुमति देता है जो यह जांचता है कि किसी निश्चित विशेषता हैश के लिए रिकॉर्ड बनाया जाना चाहिए या नहीं। हैश आपूर्ति की गई प्रक्रिया या विधि को पास कर दिया गया है और इसे या तो सत्य या गलत वापस करना चाहिए। जब नहीं: अस्वीकार_आईफ़ निर्दिष्ट किया गया है, तो सभी विशेषता हैश के लिए एक रिकॉर्ड बनाया जाएगा जिसमें _destroy मान नहीं है जो सत्य का मूल्यांकन करता है। पासिंग: प्रो की बजाय all_blank एक ऐसी प्रोजेक्ट तैयार करेगी जो रिकॉर्ड को अस्वीकार कर देगी जहां सभी गुण _destroy के लिए किसी भी मान को छोड़कर खाली हैं। – hadees

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