Rails 100%newb issue - send()方法

Ski*_*les 33 ruby ruby-on-rails send

有人可以帮我理解下面列出的'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
Run Code Online (Sandbox Code Playgroud)

表演者模特

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
Run Code Online (Sandbox Code Playgroud)

包含它的控制器是Performance.我一直在搜索谷歌试图找出'@performer.send(selected_track)'实际上正在做什么的目的,但感觉我正在对抗一个漩涡.

有人可以帮助我更好地理解这个吗?

谢谢.

ctc*_*rry 67

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
Run Code Online (Sandbox Code Playgroud)

这是基础知识,另外一条重要信息是send允许您向PRIVATE方法发送消息,而不仅仅是公共方法.

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

至于你的特定发送调用会做什么,很可能def method_missingPerformer类中有一个设置来捕获它并执行一些操作.

希望这有帮助,祝你好运!


apn*_*ing 12

send用于将方法(和参数)传递给对象.当您事先不知道方法的名称时,它非常方便,因为它只表示为字符串或符号.

例:Performer.find(params[:performer_id])与...相同Performer.send(:find, params[:performer_id])

请注意这里因为在使用时依赖params send可能是危险的:如果用户通过destroy或者delete怎么办?它实际上会删除你的对象.


Jac*_*son 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,从上面不清楚)调用它,并且它会将其解释为在该表演者的轨道内搜索该轨道.