私は悪い子で、パーシャルをレンダリングするときに値がローカルハッシュで明示的に定義されていない場合、ローカルテンプレートの次の構文を使用してローカル変数のデフォルト値を設定しました-
<% foo = default_value unless (defined? foo) %>
これは最近まで(理由はありませんが)渡されなかった変数が(未定義ではなく)nilに定義されているかのように振る舞うようになりました。
SOに関するさまざまな有用な人々から指摘されているように、 http://api.rubyonrails.org/classes/ActionView/Base.html はnot使用する
defined? foo
代わりに使用する
local_assigns.has_key? :foo
私は自分のやり方を修正しようとしていますが、それは多くのテンプレートを変更することを意味します。
事前に請求して、すべてのテンプレートでこの変更を行うことができますか?監視する必要があるトリッキーはありますか?それぞれをどれだけ熱心にテストする必要がありますか?
私はこれをします:
<% some_local = default_value if local_assigns[:some_local].nil? %>
local_assigns
はハッシュなので、オプションのdefault_value
とともに fetch を使用することもできます。
local_assigns.fetch :foo, default_value
foo
が設定されていない場合、これはdefault_value
を返します。
警告:
local_assigns.fetch :foo, default_value
がメソッドである場合、結果をfetch
に渡すためにとにかく呼び出されるので、default_value
に注意してください。
default_value
がメソッドである場合、それをブロックにラップすることができます:local_assigns.fetch(:foo) { default_value }
は、不要なときに呼び出しを防ぐことができます。
どう?
<% foo ||= default_value %>
これは「nilまたはtrueでない場合はfoo
を使用します。そうでない場合はdefault_value
をfooに割り当てます」
私はこれをここで繰り返すべきだと思います( http://api.rubyonrails.org/classes/ActionView/Base.html から):
特定のレンダリング呼び出しで特定のローカル変数に値が割り当てられているかどうかを調べる必要がある場合は、次のパターンを使用する必要があります。
<% if local_assigns.has_key? :headline %>
Headline: <%= headline %>
<% end %>
定義を使用してテストしますか?見出しは機能しません。これは実装の制限です。
私の場合、次のものを使用します。
<% variable ||= "" %>
私の部分的に。
それが良いかどうかはわかりませんが、私の場合は大丈夫です
私はそれが古いスレッドであることを知っていますが、ここに私の小さな貢献があります:パーシャル内のconditionalでlocal_assigns[:foo].presence
を使用します。次に、レンダーコールで必要な場合にのみfoo
を設定します。
<%= render 'path/to/my_partial', always_present_local_var: "bar", foo: "baz" %>
Te official Rails guide here をご覧ください。 RoR 3.1.0から有効。
これはPabloの答えの派生物です。これにより、デフォルト( 'full')を設定でき、最終的に、 'mode'はlocal_assignsと実際のローカル変数の両方に設定されます。
haml/slim:
- mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full')
erb:
<% mode ||= local_assigns[:mode] = local_assigns.fetch(:mode, 'full') %>
複数のデフォルト変数を許可するより良いオプションだと思います:
<% options = local_assigns.reverse_merge(:include_css => true, :include_js => true) %>
<%= include_stylesheets :national_header_css if options[:include_css] %>
<%= include_javascripts :national_header_js if options[:include_js] %>
より直感的でコンパクト:
<% some_local = default_value unless local_assigns[:some_local] %>
可能ですが、スコープでデフォルト値を宣言する必要があります。
変数置換するWord。
# index.html.erb
...
<%= render 'some_content', VARIABLE: false %>
...
# _some_content.html.erb
...
<% VARIABLE = true if local_assigns[:VARIABLE].nil? %>
<% if VARIABLE %>
<h1>Do you see me?</h1>
<% end %>
...
ローカル変数を呼び出すたびに部分変数に渡したくない場合は、次のようにします。
<% local_param = defined?(local_param) ? local_param : nil %>
これにより、undefined variable
エラーを回避できます。これにより、ローカル変数あり/なしでパーシャルを呼び出すことができます。