конвертировать "1.час" в 1. час - PullRequest
4 голосов
/ 09 марта 2011

Можно ли преобразовать строку "1.hour" в 1.hour и "2.hours" в 2.hours в ruby? На самом деле я получаю это значение из раскрывающегося списка в форме. Я хочу добавить к Time.now что-то вроде этого

time = Time.now + get_method(params[:hours_or_days])

, где params[:days_or_hours] может быть "2.hours" или "1.hour" или "1.day". Я хочу получить метод преобразования этих строк. Является ли это возможным? (некоторым методом, например send)

Ответы [ 3 ]

9 голосов
/ 09 марта 2011

Вы не должны делать это с eval, потому что тогда кто-то, использующий ваш сайт, может отправить вам любую строку кода Ruby, что будет плохой дырой в безопасности вашего сайта.Вы можете проверить строку, используя Regexp или белый список, но это будет грязно.

Я думаю, что вы должны оценивать 1.hour и 2.hours и так далее при рендеринге вашей формы.Примерно так:

<%= select_tag(:days_or_hours, options_for_select({ "1 hour" => 1.hour, "2 hours" => 2.hours })) %>

Это генерирует HTML следующим образом:

<select name="days_or_hours">
  <option value="3600">1 hour</option>
  <option value="7200">2 hours</option>
</select>

Теперь количество секунд будет пройдено при отправке формы, и вам не нужно беспокоитьсяо том, выбрал ли пользователь часы или дни.Ваш код просто становится:

time = Time.now + params[:days_or_hours].to_i
3 голосов
/ 09 марта 2011

Другой способ сделать это - разделить строку:

>> duration, method = '1.hour'.split('.')
 => ["1", "hour"]
>> duration.to_i.send(method)
 => 3600 seconds

Конечно, вы определенно хотели бы защитить это каким-либо образом:

if duration_string =~ /^\d+\.(hour|minute|second)s?$/
   # ...
end
0 голосов
/ 09 марта 2011

Вы можете сделать это с помощью ключевого слова eval.

например, Time.now + eval("1.hour")

Редактировать: Как уже указывалось много раз, в то время как вы можете сделатьэто, вы не должны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...