2014-01-20 28 views
2

考虑我有一个控制器,其中包含一个呈现视图的操作。该视图需要数据呈现。我知道下面的方式来准备,并将其发送到视图:清洁控制器:为视图准备数据

  1. 使用实例变量

    class CitiesController < ApplicationController 
        def index 
        @cities = Cities.order(:name).limit(10) 
        end 
    end 
    

    这是一个可以在Rails documentation找到了默认的态度,但它也有一些缺点:

    1. 它使动作码变胖,不仅对控制器逻辑负责,而且对数据准备也是负责任的。
    2. 视图需要通过实例变量访问这些数据 - 这些@变量打破了最不惊讶的原则。
  2. 使用辅助方法

    class CitiesController < ApplicationController 
        helper_method :cities 
    
        def index 
        end 
    
        def cities 
        @cities ||= Cities.order(:name).limit(10) 
        end 
    end 
    

    这就是我喜欢最的方式。它使操作方法保持清洁,所以我可以在那里实现控制器逻辑,而不是将它与数据准备工作混合在一个方法中。另外,不需要在视图中使用神秘的实例变量,使它们隔离。但是:

    1. 数据准备仍在控制器中。当有很多这些辅助方法时,尤其是当它们与不同的操作/视图相关时,它变得不可读。
    2. 需要为每个辅助方法指定一个唯一的名称。比方说,我不能有一个名为products的方法,它会针对不同的操作返回不同的数据(当然,我可以用一种方法来完成,但看起来会很难看)。
  3. 使用Facade模式

    部分问题在这篇文章中解决:https://medium.com/p/d65b86cdb5b1 但我没有,因为它在视图中引入了一个@magic_facade_object喜欢这种方式。

  4. 使用遗传资源

    它可能看起来美丽的例子,但在我看来,当涉及到真正的代码,控制器代码变成了面条怪物非常快。另一件事是页面视图通常不仅需要资源,还需要渲染其他数据(边栏模块等),我仍然需要用另一种方式来编写它。结合不同的方法使代码更加难以理解。最后,我不喜欢使用resource变量,因为它不太清楚什么是观点。

所以,这是问题所在。你如何保持你的控制器清洁?

回答

2
How do you keep your controllers clean? 

通过写DRY代码和洒一些宝石魔法周围。

看看你的要点,我想我对大多数的东西有不同的看法。

  1. @cities = Cities.order(:name).limit(10)正是我认为属于成轨道控制器,它不违反最小惊讶的原则,它是一种相反的。实例变量是将控制器中的变量传递给视图的默认方式,尽管这是一件相当丑陋的事情。这是“铁轨方式”(TM)!

  2. decent_exposure最需要的这些问题

  3. 请停止施加老派模式轨道或Ruby代码了。它在大型应用程序中非常有用,在这些应用程序中,您正在努力使单个控制器方法中的代码量保持稳定。写下干净的代码,彻底地测试它,你会在80%的时间内完好无损。

  4. 不使用“一刀切”的工具。大多数情况下,您需要编写更多的配置,而不是需要代码才能使其工作。通过这种事情也会变得更加复杂。