243

私は悪い子で、パーシャルテンプレートで次の構文を使用して、パーシャルをレンダリングするときに値が:localsハッシュで明示的に定義されていない場合に、ローカル変数のデフォルト値を設定しました-

<% foo = default_value unless (defined? foo) %>

これは、(理由もなく)渡されなかった変数が(未定義ではなく)nilに定義されているかのように動作し始めた最近まで、正常に機能しているように見えました。

SOでさまざまな役立つ人々が指摘しているように、http://api.rubyonrails.org/classes/ActionView/Base.htmlは使用しないように言っています

defined? foo

代わりに使用する

local_assigns.has_key? :foo

私は自分のやり方を修正しようとしていますが、それは多くのテンプレートを変更することを意味します。

先に請求して、すべてのテンプレートでこの変更を行うことはできますか?注意が必要なトリッキーはありますか?それぞれをどれだけ熱心にテストする必要がありますか?

4

12 に答える 12

351

私はこれをします:

<% some_local = default_value if local_assigns[:some_local].nil? %>
于 2010-01-13T23:12:48.233 に答える
171

local_assignsはハッシュなので、オプションのを使用してフェッチdefault_valueを使用することもできます。

local_assigns.fetch :foo, default_value

default_value設定されていない場合は戻りfooます。

警告:

結果をに渡すためにとにかく呼び出されるので、local_assigns.fetch :foo, default_valuewhenがメソッドであることに注意してください。default_valuefetch

default_valueがメソッドの場合は、ブロックでラップできlocal_assigns.fetch(:foo) { default_value }ます。不要なときに呼び出されないようにするためです。

于 2013-06-27T11:46:56.913 に答える
88

どうですか

<% foo ||= default_value %>

これは、「foonilまたはtrueでない場合に使用します。それ以外の場合はdefault_valuefooに割り当てます」と言います。

于 2010-01-13T22:35:17.857 に答える
13

これをここで繰り返す必要があると思います(http://api.rubyonrails.org/classes/ActionView/Base.htmlから):

特定のローカル変数が特定のレンダリング呼び出しで値を割り当てられているかどうかを確認する必要がある場合は、次のパターンを使用する必要があります。

<% if local_assigns.has_key? :headline %>
  Headline: <%= headline %>
<% end %>

定義済みを使用してテストしますか?見出しは機能しません。これは実装上の制限です。

于 2013-03-26T07:33:51.597 に答える
10

私の場合、私は以下を使用します:

<% variable ||= "" %>

私の部分で。
それが良いかどうかはわかりませんが、私にとっては大丈夫です

于 2015-05-28T22:50:59.280 に答える
5

私はそれが古いスレッドであることを知っていますが、ここに私の小さな貢献があります:私はパーシャル内の条件付きlocal_assigns[:foo].presenceで使用します。次に、render呼び出しで必要な場合にのみ設定します。foo

<%= render 'path/to/my_partial', always_present_local_var: "bar", foo: "baz" %>

こちらの公式Railsガイドをご覧ください。RoR3.1.0から有効です。

于 2014-08-28T22:04:56.893 に答える
2

これはパブロの答えの派生物です。これにより、デフォルト('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') %>
于 2014-08-13T15:59:03.317 に答える
1

複数のデフォルト変数を許可するより良いオプションだと思います。

<% 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] %>
于 2012-03-13T03:39:44.950 に答える
1

Ruby 2.5

エルブ

可能ですが、スコープでデフォルト値を宣言する必要があります。

置換のための変数。

# 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 %>
...
于 2018-08-12T15:52:24.797 に答える
0

より直感的でコンパクト:

<% some_local = default_value unless local_assigns[:some_local] %>

于 2011-11-16T20:07:34.853 に答える
0

呼び出すたびにローカル変数をpartialに渡したくない場合は、次のようにします。

<% local_param = defined?(local_param) ? local_param : nil %>

このようにして、undefined variableエラーを回避します。これにより、ローカル変数の有無にかかわらずパーシャルを呼び出すことができます。

于 2013-11-18T15:25:10.153 に答える
-6

ヘルパーは次のように作成できます。

somearg = opt(:somearg) { :defaultvalue }

次のように実装されます:

module OptHelper
  def opt(name, &block)
    was_assigned, value = eval(
      "[ local_assigns.has_key?(:#{name}), local_assigns[:#{name}] ]", 
      block.binding)
    if was_assigned
      value
    else
      yield
    end
  end
end

方法と理由の詳細については、私のブログを参照してください。

このソリューションでは、オーバーライドせずに値としてnilまたはfalseを渡すことができることに注意してください。

于 2010-03-30T02:01:38.380 に答える