28

私はERBの上に書かれたかなり古いテンプレートシステムを持っています。データベースに保存されているERBテンプレートに依存しています。それらが読み取られ、レンダリングされます。あるテンプレートから別のテンプレートにデータを渡したい場合は、:localsパラメーターをRailsレンダリングメソッドに使用します。一部のテンプレートでこれらの変数のデフォルト変数を設定するために、定義済みの変数を使用しますか?ローカル変数が定義されているかどうかを単純に通知するメソッド。定義されていない場合は、次のようにデフォルト値で初期化します。

unless defined?(perex)
  perex = true
end

アプリを最新のRailsにアップグレードしていますが、奇妙な動作が見られます。基本的に、これは機能する場合(perexが定義されていない場合)と機能しない場合(perexが定義されてnilに設定されている場合)があります。これは、他に何も変更せずに発生します。

私は2つの質問があります:定義されたものを使用する以外にもっと良い方法はありますか?信頼性が低いことを証明しているのはどれですか(Rails 1.6の上位で数年間信頼できました)?このような方法では、すべてのテンプレートを書き直す必要はありません。Rubyのドキュメントを調べましたが、定義について何も見つかりませんでしたか?方法。それは非推奨でしたか、それとも私は単なる盲目ですか?

編集:実際の問題は、Ruby/eRBのバグと思われるものが原因で発生しました。untilステートメントが機能する場合もありますが、機能しない場合もあります。奇妙なことに、2行目が実行されたとしても、perexstilは他の世界ではゼロのままでした。定義済みを削除しますか?それを解決しました。

4

4 に答える 4

39

最初: 実際にdefined?は、 は operatorです。

第二に、あなたの質問を正しく理解しているなら、それを行う方法はこのRubyイディオムです:

perex ||= true

perexそれがundefined または の場合は true を割り当てますnil。値が の場合、あなたの例は代入を評価しないため、それはあなたの例とまったく同じではありませんがnil、それに依存している場合、私の意見では、それを見ずに明確なコードを書いているわけではありません。

編集: Honza が指摘したように、上記のステートメントは の値を置き換えperexますfalse。次に、最小行数を書き直すために次のことを提案します。

perex ||= perex.nil?  # Assign true only when perex is undefined or nil
于 2008-10-26T22:26:50.793 に答える
25

Rails テンプレートでローカルが定義されているかどうかをテストする最も安全な方法は次のとおりです。

local_assigns[:perex]

これは Rails API に記載されておりdefined?、実装上の制限により使用できないという説明も含まれています。

于 2009-03-11T09:59:34.183 に答える
12

mislavの答えによると、私はRails APIでそのドキュメントを探しに行き、Class ActionView :: Base(「ローカル変数をサブテンプレートに渡す」という見出しの下)で見つけました。しかし、mislavが言ったこと以上のことはほとんど何も言わなかったので、検索する価値はほとんどありませんでした。このパターンを推奨することを除いて:

if local_assigns.has_key? :perex
于 2009-12-17T20:00:23.917 に答える
6

mislav の元の回答KenB の精緻化を考慮して、以下が絶対的な最善のアプローチだと思います (ただし、私は意見を受け入れます)。元のハッシュにキーが存在しない場合、Ruby のHash#fetchメソッドを使用して別の値にフォールバックします。

perex = local_assigns.fetch(:perex, true)

これは、値||=を許可したい場合があるため、ほとんどのユーザーが提案する方法よりも優れていfalseます。たとえば、次のコードでは、値を渡すことはできません。false

perex = local_assigns[:perex] || true
于 2012-07-23T16:42:11.823 に答える