繰り返しが必要な部分をpartialにしてしまいたくなるときがあると思います。
<% @products.each do | product | %>
<%= render ‘product’ %>
<% end %>
こうすると partialをproducts分だけ読み込むので、処理が遅くなるときがあります。
ですからこのようなループはpartialの中に入れてしまい、元の配列を渡すようにしています。
<%= render ‘products’ , products: @products %>
そしてpartialの内部で
<% products.each do |product| %>
…
<% end %>
こうすればpartialの中でループが行われるので、呼び出されるのは一度だけです。
ところがこのループの中で、それぞれのproductに対し処理を入れたいときがあります。
例えば管理者用の製品一覧画面と、ユーザー用の製品一覧画面があったとします。
管理者用の画面にはすべての製品を表示し、
ユーザー用の製品一覧画面にはプロダクトオブジェクトに公開のフラグが立っているもののみを表示したいとします。
※そもそもこの場合はコントローラー+モデルで配列自体を変更すると思いますが、あくまで例です。。
その場合、lambdaを利用してpartialに匿名関数を変数として渡す方法があります。
■管理者用のpartial呼び出し
<%= render ‘products’, products: @products,
lambda_publish: lambda{| product | true }
%>
■ユーザー用
<%= render ‘products’, products: @products,
lambda_publish: lambda{| product | product.publish?}
%>
■partial側
<% products.each do |product| %>
<% if lambda_publish.call(product) %>
..
<% end %>
<% end %>
この方法のメリットとしては、partial側を簡潔にすることができる点にあります。
他にヘルパーを使うことが一般的だと思いますが、そうするとcase-when文が登場したりしてヘルパーが太っていきます。
javascriptでよく関数を引数に渡すことがあると思いますが、それと似たような感じで使えるのでとても重宝しています。