web-dev-qa-db-ja.com

Rails 100%newbの問題-send()メソッド

以下の「send()」メソッドが何に使用されているかを理解するのを手伝ってくれませんか?以下のコードは、私がそれを読んでいるとき、それがどのような目的に使用されているのか理解できません。

RailsアプリRuby 1.8.7 with Rails 1.2.3。アップグレードはクライアントの環境なので、そんな余裕はありません。

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

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)」が実際に何をしているのかを理解するためにGoogleを調査してきましたが、ジェットバスに対して漕いでいるような気がします。

誰かがこれを理解するのを手伝ってくれませんか?

ありがとう。

34
Skittles

オブジェクトにメソッドメッセージを送信するために使用される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

これが基本です。重要な追加情報として、sendを使用すると、パブリックメソッドだけでなく、PRIVATEメソッドにメッセージを送信できます。

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

特定のsend呼び出しが何をするかに関しては、おそらくdef method_missingPerformerクラスで、それをキャッチして何らかのアクションを実行するように設定されています。

これがお役に立てば幸いです。

67
ctcherry

sendは、メソッド(および引数)をオブジェクトに渡すために使用されます。メソッドの名前が単なる文字列またはシンボルとして表されるため、事前にメソッドの名前がわからない場合に非常に便利です。

例:Performer.find(params[:performer_id])Performer.send(:find, params[:performer_id])と同じです

sendを使用するときにparamsに依存することは危険である可能性があるため、ここで注意してください。ユーザーがdestroyまたはdeleteを渡すとどうなりますか?実際にオブジェクトを削除します。

12
apneadiving

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、上記からは明確ではありません)で呼び出すことができ、それをそのトラック内での検索として解釈します。出演者のトラック。

6
Jacob Mattison