Rails技术问题:如何转义变量中的大括号?
解决Heroku环境变量中的Ruby字符串插值问题
我来帮你梳理下问题的根源和解决办法:
首先,你遇到的核心问题是环境变量里的Ruby插值语法不会被自动解析。当你在代码里直接写"https://staging.myapp.com/callback?user=#{user.id}"时,这是Ruby的字符串字面量,Ruby会自动识别#{}并执行插值;但当你从ENV["USER_ACCOUNT_URL"]取值时,拿到的只是一个普通的静态字符串,Ruby不会对它进行任何插值处理——而且Heroku的shell环境在处理环境变量时,还会把{转义成URL编码的%7B(日志里显示的#7B应该是这个编码的表现形式),所以最终生成了错误的链接。
下面给你几个可行的解决方案:
方案1:使用字符串格式化占位符(推荐)
把环境变量设置成不带Ruby语法的模板,用%{key}作为占位符:
# 在Heroku上设置环境变量 heroku config:set USER_ACCOUNT_URL="https://staging.myapp.com/callback?user=%{user_id}" -a your-staging-app
然后在Ruby代码里用String#%方法替换占位符:
new_user.callback_url = ENV["USER_ACCOUNT_URL"] % { user_id: user.id }
这种方式安全又清晰,完全避开了shell和Ruby语法冲突的问题。
方案2:用ERB解析环境变量字符串
如果你更习惯类似Ruby插值的写法,可以用ERB来解析环境变量的内容:
# 环境变量保持原来的写法 heroku config:set USER_ACCOUNT_URL="https://staging.myapp.com/callback?user=#{user.id}" -a your-staging-app
然后在代码里通过ERB触发插值:
require 'erb' # 使用binding把当前上下文的user变量传递给ERB new_user.callback_url = ERB.new(ENV["USER_ACCOUNT_URL"]).result(binding)
⚠️ 注意:这种方式要确保环境变量的内容完全受你控制,避免注入风险。
方案3:拆分环境变量
把URL的固定部分和动态部分分开,代码里手动拼接:
# 设置基础URL的环境变量 heroku config:set USER_ACCOUNT_BASE_URL="https://staging.myapp.com/callback" -a your-staging-app
然后在代码里拼接动态参数:
new_user.callback_url = "#{ENV["USER_ACCOUNT_BASE_URL"]}?user=#{user.id}"
这种方式最直观,适合参数逻辑简单的场景。
内容的提问来源于stack exchange,提问作者rlsaj
相关产品推荐
相关产品推荐

