2011-10-25 8 views
31

誰かが下記の 'send()'メソッドをどのように使っているのか理解してもらえますか?下のコードは、私がそれを読んでいるとき、それが何の目的であるのか理解できません。Rails 100%newb issue - send()メソッド

Ruby 1.8.7とRails 1.2.3を使用したRailsアプリです。アップグレードについて私を賞賛してはいけません。それはクライアントの環境なので、そんな余暇はありません。

言うまでもなく、私が言及しているステートメントはこのようです。これはに含まれている

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 

コントローラがパフォーマンスです。私は、@ performer.send(selected_track)が実際に何をしているのか把握しようとしているが、私はジェット機に漕ぐように感じている。

誰かがこのことをよりよく理解できるように助けてくれますか?

ありがとうございました。

答えて

63

オブジェクトにメソッドメッセージを送信するために使用されsend方法、のためのRubyの実装は次のように動作します。基本的です

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リファレンスについては、いいえ、Performerクラスには実際には4つのメソッドしかありません。 3(index、show、&destroy)とプライベートlookup_festivalです。それは送信が適切に動作することができないことを意味しますか? – Skittles

+0

送信は引き続き機能します。それが引き起こすのは 'selected_track'変数がそれに渡されているかどうかに依存します。あなたはそれを記録し、私たちにそれを示すことができ、私たちはあなたにもっと多くの情報を与えることができます。 – ctcherry

+0

また、パフォーマーのモデルやコントローラーを見ていますか?このsend callの問題のモデルコードを見たいと思っています。 – 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を呼び出すのと同じです。

Performerクラスは、method_missingをオーバーライドしています(これは、名前またはIDが上記の名前またはIDであるとは限りません)。そのトラック内でそのトラックを検索すると解釈されます演奏者のトラック。

+0

速いレスポンスのおかげで、JacobM!あなたの答えは本当に助けになります。混乱してしまったのは、Performerクラスには、記述したように定義されたメソッドが定義されていないということです。 @ performer.1234のあなたの例は、演奏者のインデックスメソッドを示していますか? Performerクラスでもbefore_filterが使用されていることに気付きました。 – Skittles

+1

ああ、投稿したコードが明らかになったもの。問題の 'method_missing'はActiveRecord :: Baseにあります.ActiveRecordの仕組みは、モデル上で(データベース内の)カラムを定義してから、それを呼び出します。モデル。 'Method_missing'はそのメソッド呼び出しをキャッチし、ActiveRecordはカラム/属性名で呼び出された「メソッド」とマッチします。 –

+0

これはすべて今よりはるかに良い意味を持ち始めています。私はプログラミングの古い学校から来た。 PHPとPerlであり、オブジェクト駆動の厳密なORM開発構造を頭で覆っているだけです。洞察に感謝します。大変に感謝しています。 :) – Skittles

11

sendは、メソッド(および引数)をオブジェクトに渡すために使用されます。単純に文字列や記号として表現されているので、メソッドの名前を事前に知らないと便利です。

例:Performer.find(params[:performer_id])は用心ここPerformer.send(:find, params[:performer_id])

と同じであるので、危険なことができsendを使用した場合のparamsに頼っ:ユーザーがdestroyまたはdeleteを渡したらどう?それは実際にあなたのオブジェクトを削除します。

+0

ありがとうございました!そうですか。このうちのいくつかは、今より意味をなさないようになり始めています。そして、おそらく、私は 'selected_track'変数が決してdo_scheduleメソッドに渡されなかったので、ページが投げているエラーを部分的に説明しています。 – Skittles

+0

良い解決策@apneadiving –