67

たとえば、Ryan Bates の nifty_scaffolding はこれを行います

edit.html.erb

<%= render :partial => 'form' %>

new.html.erb

<%= render :partial => 'form' %>

_form.html.erb

<%= form_for @some_object_defined_in_action %>

その隠れた状態が気持ち悪いので、普段はこうするのが好きです

edit.html.erb

<%= render :partial => 'form', :locals => { :object => @my_object } %>

_form.html.erb

<%= form_for object %>

では、どちらが優れているでしょうか: a) パーシャルにインスタンス変数にアクセスさせるか、b) パーシャルに必要なすべての変数を渡すか?

私は最近 b) を選択していましたが、ちょっとしたピクルスに出くわしました:

some_action.html.erb

<% @dad.sons.each do |a_son| %>
<%= render :partial => 'partial', :locals => { :son => a_son } %>
<% end %>

_partial.html.erb

The son's name is <%= son.name %>
The dad's name is <%= son.dad.name %>

son.dad はデータベース呼び出しを行い、お父さんを取得します! したがって、@dad にアクセスする必要があります。これは、a) パーシャルにインスタンス変数にアクセスさせるか、ローカルで @dad を渡して render :partial を <%= render :partial => 'partial' に変更する必要があります。 , :locals => { :dad => @dad, :son => a_son } %> そして、何らかの理由で、私のパーシャルに大量の変数を渡すと、不快に感じます。たぶん他の人もこのように感じているでしょう。

うまくいけば、それはある程度の意味がありました。この全体についての洞察を探しています...ありがとう!

4

4 に答える 4

107

Rails の最近のバージョンでは、パーシャルをレンダリングしてローカルに渡すのがかなり簡単になりました。これの代わりに。

<%= render :partial => 'form', :locals => { :item => @item } %>

あなたはこれを行うことができます。

<%= render 'form', :item => @item %>

下位互換性を維持するために Nifty Scaffold ジェネレーターではこれを行いませんが、将来のリリースでこれを変更します。

パーシャルでインスタンス変数を使用することが許容されるかどうかについて。それはそうですね。すべての実用性において、マイナス面は何ですか? 確かに、一貫性がないと手に負えなくなる可能性がありますが、私はこれらのガイドラインを適用したいと考えています。

  1. パーシャル間で共有するためだけにインスタンス変数を作成しないでください。通常、これはコントローラ リソース オブジェクトのみを共有することを意味します。

  2. パーシャルがリソースと同じ名前の場合は、ローカルとして渡し<%= render @item %>ます。

  3. パーシャルが複数のコントローラーで共有される場合は、ローカルのみを使用してください。

とにかくこれは私にとってうまくいくものです。

おまけのヒント:多くのローカル変数をパーシャルに渡していることに気付き、そのうちのいくつかをオプションにしたい場合は、パーシャルをレンダリングするヘルパー メソッドを作成します。次に、パーシャルをレンダリングするためのオプションの引数を使用してクリーンなインターフェイスを作成できるように、常にヘルパー メソッドを使用します。

于 2010-03-23T22:42:19.100 に答える
47

パーシャルで @instance_variables を使用するのは悪い設計です。

パーシャルでインスタンス変数を使用すると機能しますが、変更が必要になった場合にアプリケーションを維持することが難しくなる可能性があります。

パーシャルでインスタンス変数を使用することの欠点は、パーシャルのスコープ外のものへのパーシャルの依存関係 (カップリング) を作成することです。これにより、部分的な再利用が難しくなり、アプリケーションの 1 つの部分を変更したい場合に、いくつかの部分を変更する必要が生じる可能性があります。

インスタンス変数を使用するパーシャル:

  • パーシャルを使用するコントローラーのインスタンス変数が、インスタンス変数名またはその型またはデータ構造のいずれかを変更する場合は、変更する必要があります
  • インスタンス変数の使用方法が変更されたときに、パーシャルを使用するすべてのコントローラー アクションが同時に同じ方法で変更されるようにする
  • 同じ名前とデータを持つインスタンス変数を設定するアクションでのみ簡単に再利用できるため、再利用を思いとどまらせます。

代わりに、ローカルをパーシャルに渡します。

<%= render 'reusable_partial', :item => @item %>

ここで、パーシャルのみが参照され、 は参照itemされないため@item、 reusable_partial をレンダリングするビューをレンダリングするアクションは、 reusable_partial およびそれをレンダリングする他のアクション/ビューに影響を与えることなく自由に変更できます。

<%= render 'reusable_partial', :item => @other_object.item %>

また、これは @item がないコンテキストで再利用できます:

<%= render 'reusable_partial', :item => @duck %>

@duck将来変更があり、 reusable_partial が期待するようなクセがなくなった場合 (オブジェクトのインターフェイスが変更されます)、アダプターを使用して reusable_partial が期待する種類のアイテムを渡すこともできます。

<%= render 'reusable_partial', :item => itemlike_duck(@duck) %>

いつも?

このように分割されたパーシャルを必要としない状況はたくさんありますが、短期的にはインスタンス変数を使用する方が簡単です。ただし、アプリケーションの将来のニーズを予測することは困難です。

そのため、これは、比較的低コストでありながら、一般的な実践に役立ちます。

于 2012-12-06T20:41:29.270 に答える
1

私は非常に具体的な理由で a) に投票します -- DRY! そのような変数を渡し始めると、次にそれが混乱していることがわかります。変数の命名方法などを変更する必要があるとしましょう。1 つのパーシャルではなく、すべてのビューに移動して変更する必要があります。

また、パーシャルを変更すると、すべてのビューが変更されるため、どのビューが使用されているかを知る必要があります。適切な IDE がそれを支援してくれるはずですが、ビューの上部に小さなコメント セクションがあり、それがどこで使用されているのか、その理由について言及しているだけなのも気に入っています。これは別のプログラマーを助け、パーシャルに戻って変更する必要がある場合に備えて覚えておくのに役立ちます。しかし、パーシャルの全体的なポイントは、ビューから何も渡さなくてもそれを呼び出すことです。そのため、その変数が何らかの形で変更された場合に、パーシャルが呼び出されるすべての場所を変更する必要はありません。

最終的にこれは設計上の選択であり、正直に言うと、Facebook を実行していない限り、追加のルックアップはそれほど大したことではありませんが、あまり DRY ではありません。

PS: ちょっと考えてみました。ヘルパー メソッドでパーシャルを呼び出す方法を実際に抽象化できるため、パーシャルを呼び出す方法を変更する必要がある場合は、1 か所を変更するだけで済みます。

于 2010-03-23T22:21:59.477 に答える