ruby on rails - from - Rails 100% newb issue-método send()
rails yield (3)
¿Podría alguien ayudarme a entender por qué se usa el método ''send ()'' que se detalla a continuación? El código a continuación, cuando lo estoy leyendo, no tiene sentido para qué sirve.
Es una aplicación de Rails que usa Ruby 1.8.7 con Rails 1.2.3. Por favor, no me escuchen sobre la actualización, es el entorno de un cliente, así que no tengo ese tipo de ocio.
Sin embargo, es innecesario decir que la afirmación a la que me refiero es así;
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
Modelo de intérprete
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
El controlador en el que está contenido es Performance. He estado rastreando Google tratando de averiguar el propósito que ''@ performer.send (selected_track)'' está haciendo realmente, pero siento que estoy remando contra un remolino.
¿Puede alguien por favor ayudarme a tener un mejor sentido de esto?
Gracias.
El método de send
es el equivalente a llamar al método dado en el objeto. Entonces, si la variable selected_track
tiene un valor de 1234, entonces @performer.send(selected_track)
es lo mismo que @performer.1234
. O bien, si selected_track
es "a_whiter_shade_of_pale", es como llamar a @performer.a_whiter_shade_of_pale
.
Es de suponer, entonces, que la clase Performer anula method_missing
manera que puede llamarlo con cualquier pista (nombre o ID, no está claro desde arriba), e interpretará eso como una búsqueda de esa pista dentro de las pistas de ese artista intérprete o ejecutante.
La implementación de Ruby para el método de send
, que se usa para enviar un mensaje de método a un objeto, funciona así:
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
Eso es lo básico, una pieza adicional de información importante es que el envío le permitirá enviar mensajes a métodos PRIVADOS, no solo a los públicos.
@car.engine_temp # This doesn''t work, it will raise an exception
@car.send(:engine_temp) # output: Just Right
En cuanto a lo que hará su llamada de envío específico, es más que probable que exista un def method_missing
en la clase Performer
que esté configurado para atraparlo y realizar alguna acción.
Espero que esto ayude, buena suerte!
send
se usa para pasar un método (y argumentos) a un objeto. Es realmente útil cuando no se conoce de antemano el nombre del método, ya que se representa como una mera cadena o símbolo.
Ejemplo: Performer.find(params[:performer_id])
es lo mismo que Performer.send(:find, params[:performer_id])
Tenga cuidado aquí porque confiar en los parámetros al usar send
podría ser peligroso: ¿qué pasaría si los usuarios destroy
o delete
? Realmente eliminaría tu objeto.