考虑我有一个控制器,其中包含一个呈现视图的操作。该视图需要数据呈现。我知道下面的方式来准备,并将其发送到视图:清洁控制器:为视图准备数据
使用实例变量
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
的方法,它会针对不同的操作返回不同的数据(当然,我可以用一种方法来完成,但看起来会很难看)。
使用Facade模式
部分问题在这篇文章中解决:https://medium.com/p/d65b86cdb5b1 但我没有,因为它在视图中引入了一个
@magic_facade_object
喜欢这种方式。使用遗传资源
它可能看起来美丽的例子,但在我看来,当涉及到真正的代码,控制器代码变成了面条怪物非常快。另一件事是页面视图通常不仅需要资源,还需要渲染其他数据(边栏模块等),我仍然需要用另一种方式来编写它。结合不同的方法使代码更加难以理解。最后,我不喜欢使用
resource
变量,因为它不太清楚什么是观点。
所以,这是问题所在。你如何保持你的控制器清洁?