Rails 100% newb проблема - метод send()
Может ли кто-нибудь помочь мне понять, для чего используется метод send(), указанный ниже? Приведенный ниже код, когда я его читаю, не имеет никакого смысла, какую цель он обслуживает.
Это приложение Rails, использующее Ruby 1.8.7 с 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
Контроллер, в котором он содержится, - Performance. Я искал Google, пытаясь понять, какую цель выполняет "@performer.send(selected_track)", но чувствую, что я греблю против водоворота.
Может кто-нибудь, пожалуйста, помогите мне лучше понять это?
Спасибо.
Ответы
Ответ 1
Реализация Ruby для метода 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
Что основы, дополнительная важная информация - это то, что send позволит вам отправлять сообщения в методы PRIVATE, а не только публичные.
@car.engine_temp # This doesn't work, it will raise an exception
@car.send(:engine_temp) # output: Just Right
Что касается вашего конкретного запроса на отправку, более чем вероятно, что def method_missing
в классе Performer
, который настроен, чтобы поймать его и выполнить какое-либо действие.
Надеюсь, это поможет, удачи!
Ответ 2
send
используется для передачи метода (и аргументов) объекту. Это действительно удобно, когда вы не знаете заранее имя метода, потому что оно представлено как простая строка или символ.
Пример: Performer.find(params[:performer_id])
совпадает с Performer.send(:find, params[:performer_id])
Остерегайтесь здесь, потому что полагаться на параметры при использовании send
может быть опасно: что делать, если пользователи проходят destroy
или delete
? Это фактически удалит ваш объект.
Ответ 3
Метод 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
, так что вы можете вызывать его с любым треком (имя или идентификатор, это не ясно из вышесказанного), и он будет интерпретировать это как поиск этого трека в пределах что исполнитель отслеживает.