Rails 数据库字符串中的字符串插值

发布于 2024-11-25 13:48:29 字数 278 浏览 8 评论 0原文

所以这是我的问题。

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

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

"Hi #{user.name}, ...."

我尝试将其准确存储在数据库中,但它在显示在视图中之前被转义,或者在存储时被插值通过 Rails 控制台在数据库中。

提前致谢。

So here is my problem.

I want to retrieve a string stored in a model and at runtime change a part of it using a variable from the rails application. Here is an example:

I have a Message model, which I use to store several unique messages. So different users have the same message, but I want to be able to show their name in the middle of the message, e.g.,

"Hi #{user.name}, ...."

I tried to store exactly that in the database but it gets escaped before showing in the view or gets interpolated when storing in the database, via the rails console.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

妖妓 2024-12-02 13:48:29

我不认为有理由定义自定义字符串辅助函数。 Ruby 提供非常好的格式化方法,例如:

"Hello %s" % ['world']

"Hello %{subject}" % { subject: 'world' }

两个示例都返回“Hello world”。

I don't see a reason to define custom string helper functions. Ruby offers very nice formatting approaches, e.g.:

"Hello %s" % ['world']

or

"Hello %{subject}" % { subject: 'world' }

Both examples return "Hello world".

烟雨凡馨 2024-12-02 13:48:29

如果您想

"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 可能会工作得更好。

If you want

"Hi #{user.name}, ...."

in your database, use single quotes or escape the # with a backslash to keep Ruby from interpolating the #{} stuff right away:

s = 'Hi #{user.name}, ....'
s = "Hi \#{user.name}, ...."

Then, later when you want to do the interpolation you could, if you were daring or trusted yourself, use eval:

s   = pull_the_string_from_the_database
msg = eval '"' + s + '"'

Note that you'll have to turn s into a double quoted string in order for the eval to work. This will work but it isn't the nicest approach and leaves you open to all sorts of strange and confusing errors; it should be okay as long as you (or other trusted people) are writing the strings.

I think you'd be better off with a simple micro-templating system, even something as simple as this:

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

You could use whatever delimiters you wanted of course, I went with {{...}} because I've been using Mustache.js and Handlebars.js lately. This naive implementation has issues (no in-template formatting options, no delimiter escaping, ...) but it might be enough. If your templates get more complicated then maybe String#% or ERB might work better.

千纸鹤带着心事 2024-12-02 13:48:29

gsub Ruby 中的功能非常强大。

它采用哈希作为第二个参数,因此您可以为其提供要替换的密钥白名单,如下所示:

template = <<~STR
Hello %{user_email}!

You have %{user_voices_count} votes!

Greetings from the system
STR

template.gsub(/%{.*?}/, {
  "%{user_email}" => '[email protected]',
  "%{user_voices_count}" => 5,
  "%{release_distributable_total}" => 131,
  "%{entitlement_value}" => 2,
})

ERB 它是安全的。它不会抱怨单个 % 和未使用或不存在的键,例如使用 %(sprintf) 确实如此。

gsub is very powerful in Ruby.

It takes a hash as a second argument so you can supply it with a whitelist of keys to replace like that:

template = <<~STR
Hello %{user_email}!

You have %{user_voices_count} votes!

Greetings from the system
STR

template.gsub(/%{.*?}/, {
  "%{user_email}" => '[email protected]',
  "%{user_voices_count}" => 5,
  "%{release_distributable_total}" => 131,
  "%{entitlement_value}" => 2,
})

Compared to ERB it's secure. And it doesn't complain about single % and unused or inexistent keys like string interpolation with %(sprintf) does.

春花秋月 2024-12-02 13:48:29

使用 Procs 添加另一个可能的解决方案:

#String can be stored in the database
string = "->(user){ 'Hello ' + user.name}"

proc = eval(string)

proc.call(User.find(1)) #=> "Hello Bob"

Adding another possible solution using Procs:

#String can be stored in the database
string = "->(user){ 'Hello ' + user.name}"

proc = eval(string)

proc.call(User.find(1)) #=> "Hello Bob"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文