Rails:部分应该知道实例variables吗?

例如,瑞安·贝茨的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)有部分访问实例variables或者b)传递它所需要的所有variables的一部分?

我一直在selectb),但是我碰到了一个小菜。

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)具有部分访问实例variables,或者我将不得不在本地通过@dad,改变渲染:部分为<%= render:partial =>'partial' ,:locals => {:dad => @dad,:son => a_son}%>,由于某种原因,将一堆增值税传递给我的部分会让我感觉不舒服。 也许别人也这样认为。

希望这是有道理的。 寻找一些有关这整个事情的见解…谢谢!

在Rails的最新版本中,渲染局部variables和传递局部variables比较容易。 而不是这个。

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

你可以这样做。

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

我不在Nifty Scaffold生成器中执行此操作以保持向后兼容性,但是我将在以后的版本中对此进行更改。

至于是否可以使用partials中的实例variables。 我觉得是这样的。 在所有的实际中,缺点是什么? 如果你不一致,事情肯定会失控,但我喜欢应用这些指导方针。

  1. 永远不要创build一个实例variables只是为了在部分之间分享它。 通常这意味着您将只能共享控制器资源对象。

  2. 如果部分名称与资源名称相同,则将其作为本地名称传递给<%= render @item %>

  3. 如果部分将在多个控制器之间共享,那么只能使用当地人。

无论如何,这对我来说都很好。

奖金提示:如果您发现自己将许多本地人传入了部分内容,并希望其中的一部分是可选的,请创build一个呈现部分内容的辅助方法。 然后总是通过帮助器方法,所以你可以做一个干净的界面与可选参数渲染部分。

在partials中使用@instance_variables是不好的devise。

在部分工作中使用实例variables,但如果需要更改,可能会使维护应用程序变得更加困难。

在部分中使用实例variables的不利之处在于,您在部分范围(耦合)之外的部分中创build了一个依赖关系。 这使得部分难以重用,并且当您想要在一个部分中进行更改时,可以在应用程序的多个部分中强制进行更改。

使用实例variables的部分:

  • 必须在使用局部variables的任何控制器中的实例variables更改实例variables名称或其types或数据结构时更改
  • 当使用实例variables的方式发生变化的同时,使所有使用该偏移的控制器动作以相同的方式改变
  • 不鼓励重复使用,因为它们只能被轻易地用于设置具有相同名称和数据的实例variables的操作中

相反,将本地人传递给部分:

 <%= 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期望的那种types的项目:

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

总是?

有很多情况下,你可能不需要这样的分离部分,在短期内使用实例variables更容易。 但是,很难预测您的应用程序的未来需求。

因此,这在成本相对较低的情况下成为普遍的实践。

你可以有两种方式。 在你的部分顶部:

 <% item ||= @item %> 

这样,它可以或不经过本地variables,提供了一个健全的默认,但不抑制交替使用部分。

我投了一个非常具体的原因 – 干! 如果你开始传递一个variables – 就像那样 – 接下来的事情你知道 – 这是一个混乱 – 让我们假设你需要改变你的variables的名称或其他方式 – 然后你需要去所有的意见,并改变他们而不是一个部分。 另外 – 如果你改变你的偏好 – 假设它产生了一个带有一些结果的表格,它会改变你的所有视图,所以你需要知道哪些视图被使用,一个合适的IDE应该能够帮助你,但是我也喜欢在视图的顶部有一个小的注释部分 – 我只是提到它的用途和原因 – 帮助另一个程序员,它可以帮助您记住,以防您需要回到部分和修改。 但是局部的全部意义在于,不需要从视图中传递任何东西,所以如果variables以某种方式变化,就不必修改调用partial的所有地方。

最终这是一个deviseselect – 说实话,除非你正在运行一个Facebook的额外的查找你做的不是什么大不了的事情,但它不是很干。

PS:试想一下,你实际上可以抽象出你在辅助方法中调用partial的方式,那么如果你调用partial的方式需要改变 – 那么你只需要修改一个地方。