所以这是我的问题。
我想检索存储在模型中的字符串,并在运行时使用 rails 应用程序中的变量更改其中的一部分。这是一个例子:
我有一个 Message 模型,我用它来存储几个独特的消息。所以不同的用户有相同的消息,但我希望能够在消息中间显示他们的名字,例如,
"Hi #{user.name}, ...."
我试图将它准确地存储在数据库中,但它在显示在视图中之前被转义,或者在存储在数据库中时被插值,通过 rails 控制台。
提前致谢。
所以这是我的问题。
我想检索存储在模型中的字符串,并在运行时使用 rails 应用程序中的变量更改其中的一部分。这是一个例子:
我有一个 Message 模型,我用它来存储几个独特的消息。所以不同的用户有相同的消息,但我希望能够在消息中间显示他们的名字,例如,
"Hi #{user.name}, ...."
我试图将它准确地存储在数据库中,但它在显示在视图中之前被转义,或者在存储在数据库中时被插值,通过 rails 控制台。
提前致谢。
我看不到定义自定义字符串辅助函数的理由。Ruby 提供了非常好的格式化方法,例如:
"Hello %s" % ['world']
或者
"Hello %{subject}" % { subject: 'world' }
这两个示例都返回“Hello world”。
如果你想
"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。这种幼稚的实现存在问题(没有模板内格式化选项,没有分隔符转义,......)但它可能就足够了。如果您的模板变得更复杂,那么可能会String#%
或ERB
可能会更好。
我能想到的一种方法是存储模板,例如:
“你好名字”
然后在模型中有一个函数,它只是用传递的参数替换模板标签(名称)。也可以是登录的用户。
因为这个新函数将成为模型的一部分,所以您可以像在 rails 中的任何位置(包括 html.erb 文件)一样使用模型的另一个字段。
希望对您有所帮助,如果您需要更多描述,请告诉我。
gsub
在 Ruby 中非常强大。
它将散列作为第二个参数,因此您可以为其提供要替换的键的白名单:
template = <<~STR
Hello %{user_email}!
You have %{user_voices_count} votes!
Greetings from the system
STR
template.gsub(/%{.*?}/, {
"%{user_email}" => 'schmijos@example.com',
"%{user_voices_count}" => 5,
"%{release_distributable_total}" => 131,
"%{entitlement_value}" => 2,
})
使用 Procs 添加另一个可能的解决方案:
#String can be stored in the database
string = "->(user){ 'Hello ' + user.name}"
proc = eval(string)
proc.call(User.find(1)) #=> "Hello Bob"