Rails String Интерполяция в строке из базы данных
Итак, вот моя проблема.
Я хочу получить строку, хранящуюся в модели, и во время выполнения изменить ее часть с помощью переменной из приложения rails. Вот пример:
У меня есть модель сообщений, которую я использую для хранения нескольких уникальных сообщений. Поэтому разные пользователи имеют одно и то же сообщение, но я хочу, чтобы они отображали свое имя в середине сообщения, например,
"Hi #{user.name}, ...."
Я попытался точно сохранить это в базе данных, но он будет экранирован перед показом в представлении или будет интерполирован при хранении в базе данных через консоль rails.
Спасибо заранее.
Ответы
Ответ 1
Если вы хотите
"Hi #{user.name}, ...."
в вашей базе данных, используйте одинарные кавычки или выйдите из #
с обратной косой чертой, чтобы Ruby не смог сразу преобразовать содержимое #{}
:
s = 'Hi #{user.name}, ....'
s = "Hi \#{user.name}, ...."
Затем, позже, когда вы захотите сделать интерполяцию, вы могли бы, если бы вы смели или доверяли себе, используйте eval
:
s = pull_the_string_from_the_database
msg = eval '"' + s + '"'
Обратите внимание, что вам нужно будет превратить s
в строку с двойными кавычками, чтобы работать eval
. Это будет работать, но это не самый приятный подход, и вы откроете для себя всевозможные странные и запутанные ошибки, но все должно быть хорошо, если вы (или другие доверенные люди) пишете строки; Я думаю, вам будет лучше с простой системой микро-шаблонов, даже с такой простой:
def fill_in(template, data)
template.gsub(/\{\{(\w+)\}\}/) { data[$1.to_sym] }
end
#...
fill_in('Hi {{user_name}}, ....', :user_name => 'Pancakes')
Вы можете использовать любые разделители, которые вы хотели, я пошел с {{...}}
, потому что в последнее время я использую Mustache.js и Handlebars.js. У этой наивной реализации есть проблемы (нет параметров форматирования в шаблоне, без разграничения,...), но этого может быть достаточно; если ваши шаблоны усложняются, вы можете просто сохранить в базе данных бит ERB
и использовать процессор ERB в стандартной библиотеке справиться с этим.
Ответ 2
Я не вижу причины для определения настраиваемых вспомогательных функций. Ruby предлагает очень красивые подходы к форматированию, например:
"Hello %s" % ['world']
или
"Hello %{subject}" % { subject: 'world' }
Оба примера возвращают "Hello world".
Ответ 3
В один прекрасный момент я могу подумать, что это сделать, например, для хранения шаблонов:
"привет имя"
то есть функция в моделях, которая просто заменяет теги шаблона (имя) переданными аргументами.
Он также может быть Пользователем, который вошел в систему.
Поскольку эта новая функция будет частью модели, вы можете использовать ее как просто другое поле модели из любого места в рельсах, включая файл html.erb.
Надеюсь, что это поможет, дайте мне знать, если вам нужно больше описания.
Ответ 4
Добавление другого возможного решения с помощью Procs:
#String can be stored in the database
string = "->(user){ 'Hello ' + user.name}"
proc = eval(string)
proc.call(User.find(1)) #=> "Hello Bob"