清洁控制器:为视图准备数据

时间:2014-01-20 23:01:52

标签: ruby-on-rails model-view-controller

考虑我有一个带有动作的控制器来呈现视图。视图需要呈现数据。我知道以下准备方法并将其发送到视图中:

  1. 使用实例变量

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

    这是Rails documentation中可以找到的默认方法,但它有一些缺点:

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

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

    这是我最喜欢的方式。它保持动作方法的清洁,因此我可以实现控制器逻辑,而不是在一种方法中将它与数据准备混合在一起。此外,没有必要在视图中使用神秘的实例变量,使它们孤立。但是:

    1. 数据准备工作仍在控制器中。当有很多这样的帮助方法时,它变得不可读,特别是当它们与不同的动作/视图相关时。
    2. 每个帮助方法都需要一个唯一的名称。说,我不能有一个名为products的方法,它会为不同的动作返回不同的数据(当然,我可以用一种方法做,但看起来很难看)。
  3. 使用外观模式

    部分问题在本文中得到解决:https://medium.com/p/d65b86cdb5b1 但我不喜欢这种方法,因为它在视图中引入了@magic_facade_object

  4. 使用继承资源

    在示例中它可能看起来很漂亮,但在我看来,当涉及到真正的代码时,控制器代码变得非常快速的意大利面怪物。另一件事是页面视图通常不仅需要资源,还需要渲染其他数据(侧边栏等),我仍然需要使用其他方法来准备它。结合不同的方法使代码更难以理解。最后,我不喜欢使用resource变量,因为它不太清楚是什么观点。

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

1 个答案:

答案 0 :(得分:2)

How do you keep your controllers clean?

通过编写DRY代码并在周围洒上一些宝石魔法。

看看你的要点,我想我对大部分内容都有不同的看法。

  1. @cities = Cities.order(:name).limit(10)正是我认为属于rails控制器并且它没有违反最小惊喜的原则,它恰恰相反。实例变量是将变量从控制器传递到视图的默认方式,即使这是一件非常难看的事情。它是“轨道方式”(TM)!

  2. decent_exposure消除了大部分问题

  3. 请停止将旧式模式应用于rails或ruby代码。它在大型应用程序中非常有用,在这些应用程序中,您正在努力保持单个控制器方法中的代码量。写清洁代码,彻底测试,80%的时间你会很好。

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