2011-07-21 15 views
11

これは私の問題です。Rails文字列内の文字列内の補間

モデルに格納されている文字列を取得し、実行時にrailsアプリケーションの変数を使用してその一部を変更したいとします。ここに例があります:

私はいくつかの一意のメッセージを格納するために使用するメッセージモデルを持っています。だから私は、データベースに正確にそれを保存しようとしましたが、それはで表示する前に脱出します別のユーザーが同じメッセージを持っているが、私は、メッセージの途中で自分の名前を表示できるようにしたい、例えば、

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

ビューは、レールコンソールを介して、データベースに格納するときに補間されます。

ありがとうございます。私はこれを行うと考えることができ

答えて

9

は、すぐに#{}ものを補間からルビーを保つために単一引用符を使用するか、バックスラッシュで#を逃れますもしあなたが大胆で信頼できるものであれば、あなたは補間をしたいと思っています。eval

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

evalを動作させるには、sを二重引用符で囲む必要があります。これは動作しますが、それは最も良いアプローチではなく、あらゆる種類の奇妙で混乱しているエラーにあなたを晒していますが、あなた(または他の信頼できる人)が文字列を書いている限り、大丈夫です。私はあなたが簡単なマイクロテンプレートシステムを持つ方が良いと思う、このような単純なでも何か:

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プロセッサを使用することができます。

+0

ありがとう、それは働いた... 私はすでに単一引用符で囲まれた文字列を格納していました。私はちょうどデータベースからそれを取得した後に補間する方法が不足していた。 これを使用するとセキュリティリスクが発生しますが、ユーザーはこの文字列を直接変更することはできません。 –

+0

文字列にHTMLが含まれている場合は 'raw'(http://apidock.com/rails/ActionView/Helpers/OutputSafetyHelper/raw)メソッドと' html_safe'メソッドを使用して追加します。 – dennismonsewicz

0

一つの方法は、例えば保存されたテンプレートを持つことです。

「HI名」

はその後、ちょうど渡されてテンプレートタグ(名前)を置き換えるモデルでの機能を持っています議論 ログインしたユーザーでもかまいません。

この新しい機能はモデルの一部であるため、html.erbファイルを含むレールの任意の場所からモデルの別のフィールドのように使用できます。

希望があれば、もっと詳しく説明する必要がある場合はお知らせください。

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

を次に、後でとき:あなたは、データベース内の

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

をしたい場合は

+0

私はそれを得る、私はそれが仕事だと思う、私はこの中で見るの問題は、私はそれぞれを使用してマッピングすることができるすべての可能なタグを定義しなければならないということです1つはアプリケーション内のそれぞれの変数/関数に割り当てられます。通常の文字列の補間のように、これを行う簡単な方法があると思っただけです。 –

+0

あなたのアプローチもうまくいくと思います。ダブルクォートの代わりにシングルクォートを使用して文字列を作成することで、データベースに格納する前に補間する文字列を避けることができます。私はなぜそれが見に来る前にエスケープされるのか分からない。 – Shaunak

+0

私は単一引用符付きのバージョンを格納していましたが、データベースに保存する前にエスケープされた二重引用符で囲まれた文字列に変換されます。 –

34

カスタム文字列ヘルパー関数を定義する理由はありません。 Rubyはvery nice formatting approachesを提供します。:

"Hello %s" % ['world'] 

または

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

どちらの例では、 "こんにちは、世界" を返します。

+5

これはimho問題の最もエレガントかつ簡単な解決策です – januszm

+1

私は同意します。これは、既存の機能を使用する最も簡単なソリューションです。 – CDub

0

手続きオブジェクトを使用して、別の可能な解決策の追加:

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

proc = eval(string) 

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