それが私のプロジェクトであれば、おそらくこの問題を JavaScript 側に移すでしょう。緯度と経度を item タグのどこかにある data- 属性に入れ、目立たないスクリプトを使用してそれらを読み取ります。(例が必要な場合はお知らせください。)
それが不可能な場合、私は個人的にオプション A を好みます。まず第一に読みやすさ (特に content_for に慣れていない場合は理解しやすい) と第二に、リファクタリングが容易であるため、データの収集をメソッドに移動できます。モデルまたはヘルパーに。ここでは DRY は実際には適用されません。同じデータセットをループしている場合でも、非常に異なることを行っているからです。
とはいえ、パフォーマンスへの影響についてはよくわからなかったので、少しテストを実行しました。私は自分のアプリの 1 つで 500 のクライアント レコードを取得し、オプション A を使用してリンクのリストをレンダリングし、続いてそれらのデータを content_for ブロックにマッピングし、Ruby の組み込み Benchmark モジュールを使用してベンチマークを行いました (erb ではなく haml ですが、私は確信しています読みにくいわけではありません。)
- bench = Benchmark.measure do
%ul#client-list
- @clients.each do |client|
%li
= link_to client.company, client
- content_for :foobar do
= "['#{j client.name}', '#{j client.company}', '#{j client.email}'],"
= javascript_tag do
var nearbys = [#{yield :foobar}];
%p= bench.to_s
結果、約370ミリ秒
0.370000 0.000000 0.370000 ( 0.397476)
次に、2 つのループ (1つ 1each
つmap
)で同じことを行いました。
- bench = Benchmark.measure do
%ul#client-list
- @clients.each do |client|
%li
= link_to client.company, client
= javascript_tag do
= "var nearbys = [#{ @clients.map { |client| "['#{j client.name}', '#{j client.company}', '#{j client.email}']," }}]"
%p= bench.to_s
結果、約 80 ミリ秒:
0.080000 0.000000 0.080000 ( 0.077940)
自分で結果を確認したいかもしれませんが、この問題を解決するには content_for メソッドはあまり効率的ではないようです。
編集:参考までに、これはree 1.8.7とrails 3.2.6を使用してテストされました
編集2:
インライン JavaScript を使用せずにこれを書き換える方法の例。まず、必要なすべてのパラメーターをdata-
ビューなどの属性に移動します。
<% @items.each do |item| %>
<div class="item" data-name="<%= item.name %>"
data-lat="<%= item.lat %>"
data-long="<%= item.long %>">
<%= item.name %>
</div>
<% end %>
(div 内から名前を取得することもできますが、すべてを data-attributes に入れる方が一貫性があります。)
次に、JavaScriptで次のようにデータをマップできます(jqueryを想定):
var nearbys = $('.item').map(function() {
return [ $(this).data("name"), $(this).data("lat"), $(this).data("long") ];
});
このようにして、すべての JavaScript を別のファイルにきちんと保持し、データの収集をクライアント側で行うことができます。