2010-02-11 2 views
2

У меня есть модель пользователя с рядом очень похожих свойств, которые я хочу перечислить, не набирая каждый по отдельности.Ruby: Как высушить аналогичные вызовы атрибутов модели

Таким образом, вместо:

"eye color: #{@user.his_eye_color}" 
"hair color: #{@user.his_hair_color}" 
"height: #{@user.his_height}" 
"weight: #{@user.his_weight}" 
... 

"eye color: #{@user.her_eye_color}" 
"hair color: #{@user.her_hair_color}" 
"height: #{@user.her_height}" 
"weight: #{@user.her_weight}" 
... 

Я хотел бы сделать блок или что-то (Proc Lambda Еще сенсорную неясным, что те ...?):

['eye color','hair color','height','weight',...].do |stat| 
    "#{stat}: #{@user.her_(stat.underscore)}" 
end 

['eye color','hair color','height','weight',...].do |stat| 
    "#{stat}: #{@user.his_(stat.underscore)}" 
end 

Я знаю, что то, что я только что написал выше, является мистическим, магическим и полностью и полностью НЕПРАВИЛЬНЫМ (часть @user.his_(stat.underscore)), но что я могу сделать так? Мне в основном нужно динамически называть атрибуты моей модели, но я не уверен, как это сделать ...

Любая помощь была бы действительно оценена!

ответ

2

Если вы используете ActiveRecord в Rails, вы также можете использовать метод Object # [] для динамического получения значений атрибутов

['eye color','hair color','height','weight',...].do |stat| 
    "#{stat}: #{ @user[ "her_#{ stat.underscore }"]}" 
end 
+0

Я использую Rails, и этот метод работает тоже ... кроме того, что я до сих пор не имею доступа к '.underscore'. – neezer

+0

В соответствии с подчеркиванием под названием Rails API «EyeColor» превратится в «eye_color», но оставить «цвет глаз» в одиночку. – Farrel

+0

Я использовал комментарий bta от другого ответа с помощью вашего метода Object # [], и он работает, и он выглядит очень чистым! Благодаря! – neezer

5
['eye color','hair color','height','weight',...].do |stat| 
    "#{stat}: #{ @user.send(:"her_#{stat.tr(" ","_")}") }" 
end 

['eye color','hair color','height','weight',...].do |stat| 
    "#{stat}: #{ @user.send(:"his_#{stat.tr(" ","_")}") }" 
end 

Это должно сработать. Вы всегда можете использовать метод для вызова метода на объект и генерировать это имя метода на ходу как строку

+0

Я знал, что должно быть что-то вроде этого мне не хватало ... однако, '.underscore', похоже, перестает работать, поэтому вызов терпит неудачу. Любая идея, почему это так? – neezer

+0

Подчеркивание возможно доступно только из ActiveSupport в Rails. Я не думаю, что он доступен в стандартном Ruby String API. – Farrel

+2

Если ничего больше, 'stat' - это строка, поэтому вы всегда можете использовать' stat.tr ('', '_') 'для их преобразования, если вы не можете заставить' .underscore' работать. – bta

Смежные вопросы