Rails字符串从数据库中插入字符串

Rap*_*elo 18 ruby string string-interpolation ruby-on-rails-3

所以这是我的问题.

我想检索存储在模型中的字符串,并在运行时使用rails应用程序中的变量更改其中的一部分.这是一个例子:

我有一个Message模型,我用它来存储几个独特的消息.所以不同的用户有相同的消息,但我希望能够在消息的中间显示他们的名字,例如,

"Hi #{user.name}, ...."
Run Code Online (Sandbox Code Playgroud)

我试图在数据库中存储它,但它在视图中显示之前被转义,或者在存储在数据库中时通过rails控制台进行插值.

提前致谢.

Seb*_*eer 51

我没有看到定义自定义字符串辅助函数的原因.Ruby提供了非常好的格式化方法,例如:

"Hello %s" % ['world']
Run Code Online (Sandbox Code Playgroud)

要么

"Hello %{subject}" % { subject: 'world' }
Run Code Online (Sandbox Code Playgroud)

两个例子都返回"Hello world".

  • 这是对这个问题最优雅,最简单的解决方案 (6认同)
  • 我同意.这是使用现有功能的最简单的解决方案. (3认同)

mu *_*ort 18

如果你想

"Hi #{user.name}, ...."
Run Code Online (Sandbox Code Playgroud)

在您的数据库中,使用单引号或#使用反斜杠转义以防止Ruby立即插入#{}内容:

s = 'Hi #{user.name}, ....'
s = "Hi \#{user.name}, ...."
Run Code Online (Sandbox Code Playgroud)

然后,当你想要进行插值时,如果你自己大胆或信任,可以使用eval:

s   = pull_the_string_from_the_database
msg = eval '"' + s + '"'
Run Code Online (Sandbox Code Playgroud)

请注意,您必须s变成双引号字符串才能eval使其工作.这可行,但它不是最好的方法,让你对各种奇怪和混乱的错误开放; 只要你(或其他可信赖的人)正在写字符串就应该没问题.

我认为使用简单的微模板系统会更好,即使是这样简单的事情:

def fill_in(template, data)
  template.gsub(/\{\{(\w+)\}\}/) { data[$1.to_sym] }
end
#...
fill_in('Hi {{user_name}}, ....', :user_name => 'Pancakes')
Run Code Online (Sandbox Code Playgroud)

你可以使用任何你想要的,当然分隔符,我去了{{...}},因为我一直在使用Mustache.js和Handlebars.js最近.这个天真的实现有问题(没有模板内格式化选项,没有分隔符转义,......)但它可能就足够了.如果您的模板变得更复杂,那么可能String#%ERB可能更好.