`yield :foo`と`content_for :foo`の使い分け

21 views Post
wakairo @wakairo

動機

Rails 8.0.2でrails newをして生成されたapp/views/layouts/application.html.erbでは、 以下のようにyield :foocontent_for :fooが混在していました。

<html>
  <head>
    <title><%= content_for(:title) || "Sample" %></title>
(中略)
    <%= yield :head %>

content_forのAPIドキュメントによれば yield :foocontent_for :fooの働きが等価となる場合もあるのですが、 このapplication.html.erbの例のように、片方に統一されず両方を利用しているケースがあったので、 yield :foocontent_for :fooの使い分けについて調べる事にしました。

結論

  • 基本的には、yield :fooを使う。ただし、以下の2つのケースではcontent_for :fooを使う。
  • ケース1:ヘルパーメソッドの中では、yieldは利用できないので、content_for :fooを使う。
  • ケース2:ビュー側で設定されているかどうかに応じて挙動を切り替えるコードを短く書くときにはcontent_for :fooを使う。

詳細

yieldはヘルパーメソッドの中では利用できない

content_forのAPIドキュメントに書かれている通り、 content_forは以下の例のようにヘルパーメソッド内で利用可能ですが、yieldは利用できません。

module StorageHelper
  def stored_content
    content_for(:storage) || "Your storage is empty"
  end
end

yieldとcontent_forでは、設定されていないときの戻り値が異なる

ビュー側で以下のように:fooに対して設定が行われていた場合、

<% content_for :foo do %>
  Foo
<% end %>

yield :foocontent_for :fooの戻り値は、この例ではどちらも" Foo\n"であり、同じになります。

しかし、ビュー側で前述のような記述がなく:fooに対して設定が行われていなかった場合、 yield :fooの戻り値が空文字列("")であるのに対し、content_for :fooの戻り値はnilであり、 戻り値が異なります。

設定されていない場合にcontent_for :foonilを戻す性質を利用することで、<title><%= content_for(:title) || "Sample" %></title>のような設定されているかどうかに応じて挙動を切り替えるコードを短く書くことができます。

0
Raw
https://www.techtips.page/en/comments/1040