【发布时间】:2014-02-10 07:50:30
【问题描述】:
假设我有一个控制器,它带有一个呈现视图的操作。视图需要数据来呈现。我知道以下方法来准备并将其发送到视图:
-
使用实例变量
class CitiesController < ApplicationController def index @cities = Cities.order(:name).limit(10) end end这是Rails documentation中可以找到的默认方法,但它有一些缺点:
- 它使动作代码变胖,不仅负责控制器逻辑,还负责数据准备。
- 视图需要通过实例变量访问这些数据——那些@变量违反了最小惊讶原则。
-
使用辅助方法
class CitiesController < ApplicationController helper_method :cities def index end def cities @cities ||= Cities.order(:name).limit(10) end end这是我最喜欢的方式。它使动作方法保持干净,因此我可以在那里实现控制器逻辑,而不是在一种方法中将其与数据准备混合。此外,无需在视图中使用神秘的实例变量,使它们相互隔离。然而:
- 数据准备仍在控制器中。当有很多这些帮助方法时,它变得不可读,尤其是当它们与不同的操作/视图相关时。
- 需要为每个辅助方法指定一个唯一的名称。比如说,我不能有一个名为
products的方法,它会为不同的操作返回不同的数据(当然,我可以用一种方法来做,但看起来很难看)。
-
使用外观模式
本文部分解决了问题:https://medium.com/p/d65b86cdb5b1 但我不喜欢这种方法,因为它在视图中引入了
@magic_facade_object。 -
使用继承的资源
在示例中它可能看起来很漂亮,但在我看来,当涉及到真正的代码时,控制器代码很快就变成了意大利面怪物。另一件事是页面视图通常不仅需要资源,还需要其他数据来呈现(侧边栏块等),我仍然必须使用另一种方式来准备它。结合不同的方法使代码更加不可读。最后,我不喜欢使用
resource变量,因为它不太清楚视图是关于什么的。
那么,问题来了。如何保持控制器清洁?
【问题讨论】:
标签: ruby-on-rails model-view-controller