2012-11-14 14 views
5

यह रूबी/रेल के साथ मेरे साथ सबसे अजीब बात है।ऑब्जेक्ट लोड नहीं होता

मेरे पास एक मॉडल है, स्टोर, जिसमें है_many शेष। और मेरे पास एक तरीका है जो मुझे स्टोर की मुद्रा के आधार पर डिफ़ॉल्ट संतुलन देता है।

स्टोर मॉडल।

class Store < ActiveRecord::Base 

    has_many :balances, as: :balanceable, dependent: :destroy 

    def default_balance 
    #puts self.inspect <- weird part. 
    balances.where(currency: self.currency)[0] 
    end 
    ... 
end 

शेष मॉडल।

class Balance < ActiveRecord::Base 

    belongs_to :balanceable, :polymorphic => true 
    ... 
end 

ठीक है, तो फिर शेष नियंत्रक में मैं कार्रवाई दिखाने के लिए, कि मुझे एक विशिष्ट संतुलन या डिफ़ॉल्ट एक दे देंगे।

बैलेंस नियंत्रक।

class Api::Stores::BalancesController < Api::Stores::BaseController 

    before_filter :load_store 

    # Returns a specific alert 
    # +URL+:: GET /api/stores/:store_id/balances/:id 
    def show 
    #puts @store.inspect <- weird part. 
    @balance = (params[:id] == "default") ? @store.default_balance : Balance.find(params[:id]) 
    respond_with @balance, :api_template => :default 
    end 
    ... 

    private 
    # Provides a shortcut to access the current store 
    def load_store 
     @store = Store.find(params[:store_id]) 
     authorize! :manage, @store 
    end 
end 

अब यहाँ जहां अजीब हिस्सा आता है मैं इस शो कार्रवाई के लिए एक फोन करना है ...

;

प्राप्त/API/भंडार/148/शेष राशि/डिफ़ॉल्ट

यह अशक्त रिटर्न (क्योंकि मुद्रा अशक्त के रूप में स्थापित किया गया था, और वहाँ शून्य मुद्रा के साथ कोई शेष है) और: उदाहरण के लिए एसक्यूएल उत्पन्न क्वेरी है:

SELECT `balances`.* FROM `balances` WHERE `balances`.`balanceable_id` = 148 AND `balances`.`balanceable_type` = 'Store' AND `balances`.`currency` IS NULL 

तो मैं नहीं जानता कि क्यों ... यह NULL रूप मुद्रा स्थापित कर रही है। लेकिन अगर उस प्रक्रिया में किसी भी जहां में मैं डाल

या default_balance विधि के अंदर @ store.inspect कहते हैं:

self.inspect डालता

यह जादुई काम करता है !!!

तो मुझे नहीं पता कि यह क्यों हो रहा है? ... ऐसा लगता है कि स्टोर ऑब्जेक्ट लोड नहीं हो रहा है जब तक कि मैं का निरीक्षण करता हूं "या ऐसा कुछ।

धन्यवाद

+0

'तालिका भंडार का एक स्तंभ currency' है? – Yanhao

+0

हां, यह है। 'मुद्रा: स्ट्रिंग (255)' – esbanarango

+0

क्वेरी –

उत्तर

0

ठीक अंत में डिबगिंग का एक बहुत बाद, मुझे कारण मिला ...

def method_missing method_name, *args 
    if method_name =~ /^(\w+)_togo$/ 
    send($1, *args).where(togo: true) 
    elsif method_name =~ /^(\w+)_tostay$/ 
    send($1, *args).where(tostay: true) 
    end 
end 

तो जब मैं यह method_missing के लिए सबसे पहले हो गया था और उसके बाद अशक्त लौटे self.currency बुला गया था:

स्टोर मॉडल में मैं एक method_missing विधि है और मैं इसे इस तरह था। मैं यहां क्या खो रहा था super कॉल था।

def method_missing method_name, *args 
    if method_name =~ /^(\w+)_togo$/ 
    send($1, *args).where(togo: true) 
    elsif method_name =~ /^(\w+)_tostay$/ 
    send($1, *args).where(tostay: true) 
    else 
    super 
    end 
end 

लेकिन मैं सोच क्यों के बाद मैं puts @store.inspect बुलाया था या puts self.inspect यह अच्छी तरह से काम जारी रखने के लिए ?. मेरा मतलब है, उस मामले में क्यों super कॉल की आवश्यकता नहीं थी?

+1

शायद क्योंकि 'निरीक्षण' एक कॉल करें जो तालिका में सभी कॉलम के लिए विधियों को परिभाषित करता है। –

+0

एड्रियान सही है- 'ऑब्जेक्ट' को 'ऑब्जेक्ट' में परिभाषित किया गया है, जिससे आपका निस्संदेह उतरता है। 'method_missing' केवल तब कॉल किया जाता है जब विधि कक्षा में और उसके पूर्वजों में से कोई नहीं पाई जाती है। –

1

सैम और एड्रियन सही रास्ते पर हैं।

ActiveRecord स्टोर # मुद्रा की तरह स्तंभ समर्थित विशेषताओं के लिए accessors सहित गतिशील तरीकों की एक पूरी गुच्छा जोड़ने के लिए method_missing ओवरराइड करता है। जब मैं एक बहुत अधिक glossing कर रहा हूँ, यह कहना है कि जब तर्क तो शुरू हो जाती है गतिशील वर्ग/उदाहरण तरीकों स्टोर वर्ग/उदाहरणों में जोड़ा जाता है ताकि आगामी कॉल अब method_missing हुक की आवश्यकता होती है पर्याप्त।

जब आप सुपर बुला बिना method_missing overrode, आप प्रभावी रूप से इस कार्यक्षमता अक्षम। सौभाग्य से, इस कार्यक्षमता को अन्य माध्यमों से बुलाया जा सकता है, जिसमें से एक जिसे आपने स्टोर # निरीक्षण कहा था।

सुपर को कॉल जोड़कर, आपने बस आश्वस्त किया कि जब आवश्यक हो तो ActiveRecord की गतिशील विधियों को कक्षा में हमेशा जोड़ा जाता है।

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