2011-10-25 11 views
31

क्या कोई मुझे समझने में मदद कर सकता है कि नीचे सूचीबद्ध 'भेजें()' विधि का उपयोग किस प्रकार किया जाता है? नीचे दिया गया कोड, जब मैं इसे पढ़ रहा हूं, तो इसका कोई मतलब नहीं है कि यह किस उद्देश्य से सेवा कर रहा है।रेल 100% नया मुद्दा - भेजें() विधि

यह रेल 1.2.3 के साथ रूबी 1.8.7 का उपयोग कर एक रेल ऐप है। कृपया उन्नयन के बारे में मुझे परेशान न करें, यह एक ग्राहक का पर्यावरण है, इसलिए मेरे पास उस तरह का अवकाश नहीं है।

हालांकि कहने की जरूरत नहीं है, मैं जिस बयान का जिक्र कर रहा हूं वह इस तरह है;

def do_schedule 
    @performance = Performance.new(params[:performance]) 
    @performer = Performer.find(params[:performer_id]) 
    selected_track = params[:selected_track] 
    if FileTest.exists?(File.expand_path(@performer.photo)) 
    @performance.photo = File.open(File.expand_path(@performer.photo)) 
    end 

    @performance.audio = File.open(File.expand_path(@performer.send(selected_track))) 

    if @performance.save 
    flash[:notice] = 'Performer scheduled.' 
    redirect_to :controller => :performer, :action => :index 
    else 
    render :action => 'schedule' 
    end 
end 

कलाकार मॉडल

class Performer < ActiveRecord::Base 
    file_column :audio_one 
    file_column :audio_two 
    file_column :audio_three 
    file_column :photo 

    belongs_to :festival 
    validates_presence_of :name, :first_name, :last_name, :address, :city, :state, :zip, :daytime_phone, :availability, :stages 
    validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i 
    validates_confirmation_of :email 

    validates_presence_of :audio_one, :audio_two, :audio_three, :photo, :if => :submitted 

    after_create :salt_access_key 
    serialize :availability 
    serialize :stages 

    attr_accessor :other_type_of_music 
    before_save :set_other_type 

    def set_other_type 
    if type_of_music == 'Other' 
     self.type_of_music = "Other - #{other_type_of_music}" unless other_type_of_music.blank? 
    end 
    end 

    def salt_access_key 
    update_attribute(:access_key, Digest::SHA1.hexdigest("--#{self.id}--#{self.name}--#{self.festival.year}")) 
    end 

    def preferred_stages 
    stages = [] 
    festival = Festival.find(self.festival_id.to_i) 
    self.stages.collect { | key, value | 
     id = key.gsub(/[\D]/, '').to_i 
     if id > 0 
     stages << festival.performance_stages.find(id).name 
     end 
    } 
    return stages 
    end 
end 

नियंत्रक है कि इस में निहित है प्रदर्शन है। मैं Google को यह समझने की कोशिश कर रहा हूं कि 'performer.send (select_track) वास्तव में क्या कर रहा है, लेकिन ऐसा लगता है कि मैं एक भंवर के खिलाफ रो रहा हूं।

क्या कोई मुझे इस से बेहतर समझने में मदद कर सकता है?

धन्यवाद।

उत्तर

63

send विधि है, जिसमें एक वस्तु के लिए एक विधि संदेश भेजने के लिए प्रयोग किया जाता है के लिए रूबी कार्यान्वयन, इस तरह काम करता है:

class Car 

    def start 
    puts "vroom" 
    end 

    private 

    def engine_temp 
    puts "Just Right" 
    end 

end 

@car = Car.new 
@car.start # output: vroom 
@car.send(:start) # output: vroom 

मूल बातें, महत्वपूर्ण जानकारी का एक अतिरिक्त टुकड़ा है यही कारण है कि भेजने की अनुमति देगा आप निजी संदेशों को संदेश में भेजते हैं, सिर्फ सार्वजनिक नहीं।

@car.engine_temp # This doesn't work, it will raise an exception 
@car.send(:engine_temp) # output: Just Right 

अपने विशिष्ट भेजने कॉल क्या करेंगे का सवाल है, संभावना से भी अधिक वहाँ Performer वर्ग है कि कि पकड़ने और कुछ कार्रवाई करने के लिए सेटअप में एक def method_missing है।

उम्मीद है कि यह मदद करता है, शुभकामनाएँ!

+0

धन्यवाद ctcherry! महान उदाहरण! आपके द्वारा अभी किए गए method_missing संदर्भ के लिए। नहीं, वास्तव में कलाकार वर्ग में केवल 4 तरीके हैं। 3 (इंडेक्स, शो, और नष्ट) और एक निजी lookup_festival। क्या इसका मतलब यह है कि प्रेषण ठीक से काम करने में असमर्थ है? – Skittles

+0

भेजें अभी भी काम करेगा। यह ट्रिगरिंग क्या करता है इस पर निर्भर करता है कि 'select_track' चर क्या है जिसमें इसे पारित किया जा रहा है। आप इसे लॉग कर सकते हैं और इसे हमें दिखा सकते हैं और हम आपको अधिक जानकारी दे सकते हैं। – ctcherry

+0

इसके अलावा, क्या आप कलाकार मॉडल या नियंत्रक में देख रहे हैं? आप इस प्रेषण कॉल मुद्दे के लिए मॉडल कोड देखना चाहते हैं। – ctcherry

6

send विधि ऑब्जेक्ट पर दी गई विधि को कॉल करने के बराबर है। तो यदि selected_track वैरिएबल का मान 1234 है, तो @performer.send(selected_track)@performer.1234 जैसा ही है। या, यदि selected_track "a_whiter_shade_of_pale" है तो यह @performer.a_whiter_shade_of_pale पर कॉल करना है।

संभवतया, परफॉर्मर क्लास method_missing ओवरराइड करता है जैसे कि आप इसे किसी भी ट्रैक (नाम या आईडी के साथ कॉल कर सकते हैं, यह उपर्युक्त से स्पष्ट नहीं है), और यह उस ट्रैक के लिए उस खोज के रूप में व्याख्या करेगा कलाकार के ट्रैक।

+0

तेज प्रतिक्रिया के लिए धन्यवाद, जैकब एमएम! आपका जवाब वास्तव में बहुत मदद करता है।मुझे लगता है कि मुझे एक उलझन में क्या मिला है यह है कि परफॉर्मर क्लास में एक विधि परिभाषित नहीं है जिसे आपके द्वारा वर्णित कहा जाएगा। क्या आपके प्रदर्शनकर्ता के इंडेक्स विधि का @ performer.1234 संकेतक का उदाहरण है जिसे प्रेषण के परिणाम के रूप में बुलाया जा रहा है या क्या? मैंने देखा कि परफॉर्मर क्लास में पहले_फिल्टर भी इस्तेमाल किया जा रहा है। – Skittles

+1

आह, कोड आपने स्पष्ट चीजें पोस्ट की हैं। प्रश्न में 'method_missing' ActiveRecord :: बेस में है - जिस तरह से ActiveRecord काम करता है वह है कि मैं एक मॉडल पर एक कॉलम (डेटाबेस में) परिभाषित कर सकता हूं, और फिर इसे कॉल कर सकता हूं भले ही यह परिभाषित विधि न हो आदर्श। 'Method_missing' उस विधि कॉल को पकड़ता है और ActiveRecord कॉलम/विशेषता नाम के साथ बुलाए गए "विधि" से मेल खाता है। –

+0

यह सब अब बेहतर समझने के लिए शुरू कर रहा है। मैं प्रोग्रामिंग के पुराने स्कूल से आया हूँ। PHP और पर्ल और अब केवल ऑब्जेक्ट-संचालित सख्त ओआरएम विकास संरचनाओं के चारों ओर अपना सिर लपेट रहा है। अंतर्दृष्टि के लिए धन्यवाद। इसकी बहुत सराहना की गई थी। :) – Skittles

11

send किसी ऑब्जेक्ट को विधि (और तर्क) पास करने के लिए उपयोग किया जाता है। यह वास्तव में आसान है जब आप पहले से ही विधि का नाम नहीं जानते हैं, क्योंकि इसे केवल स्ट्रिंग या प्रतीक के रूप में दर्शाया जाता है।

पूर्व: Performer.find(params[:performer_id])Performer.send(:find, params[:performer_id])

यहाँ खबरदार रूप में ही है, क्योंकि जब send का उपयोग कर खतरनाक हो सकता है पैरामीटर पर निर्भर: क्या हुआ अगर उन destroy या delete पारित? यह वास्तव में आपकी वस्तु को हटा देगा।

+0

धन्यवाद apneadiving! समझा। इनमें से कुछ अब और अधिक समझना शुरू कर रहा है। और शायद यह आंशिक रूप से एक त्रुटि समझा रहा है कि पृष्ठ फेंक रहा है क्योंकि 'select_track' चर को कभी भी मैं बता सकता हूं कि do_schedule विधि को कभी नहीं भेजा गया था। – Skittles

+0

अच्छा समाधान @apneadiving –

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