【问题标题】:What are some options for keeping controllers lean in Rails 4?在 Rails 4 中保持控制器精简的选项有哪些?
【发布时间】:2014-04-12 02:16:13
【问题描述】:

背景

我对 Rails 还很陌生。我正在与 Ruby 2.1.1Rails 4.1 合作,并且已经阅读了很多书籍和教程,但还没有完全理解什么是保持控制器精简的最佳方法。

看起来在 Rails 4 中,concerns 可用于模型和控制器。至少对于控制器而言,主要目的似乎是帮助保持路由和控制器DRY。一个很好的例子似乎是defensible example at codeschool

我还阅读了一些关于类似问题的问题,但找不到我认为完全匹配的内容,尤其是在 Rails 4 的上下文中。我所看到的似乎表明可以创建自定义类或模块,然后在控制器操作中调用它。

具体问题

  • 我有一个控制器,其中大部分操作都很精简,但有一个必须进行大量数据处理,这个控制器已经变得非常大
  • 我在控制器中创建了一些私有 helper methods 以将处理分成更小的部分 - 但似乎这些 应该几乎组合成一个模块或类?
  • 数据处理确实是该控制器特有的,不太可能在其他地方使用

问题

  1. 我觉得这个控制器不应该有一个大而臃肿的动作是正确的吗?或者说控制器的action变大这样正常吗?
  2. 关注点是否旨在帮助减少这种情况?还是它们更有助于不同控制器之间共享操作的 DRY 方面?
  3. 类或模块会是一个好的解决方案吗?创建自定义类/方法来帮助保持控制器精简是典型的做法吗?
  4. 如果类/模块方法是一个好的解决方案,那么如何选择模块与类?
  5. 如果类/模块方法是一个很好的解决方案,它们应该放在哪里以及应该如何加载/调用它们? (如果它们只特定于一个控制器,它们似乎不应该是全局“帮助”函数)

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 controller dry


    【解决方案1】:
    1. 取决于 - 如果您必须在控制器中处理该数据,也许这是正确的方法。但与大多数事情一样,如果您向我们展示代码,我们也许可以进行重构。您需要注意modularity,这意味着您应该尽可能多地拆分代码,以鼓励重用

    2. 真正关心的是提供跨控制器/跨模型模块化。比如我们在几个模型中使用friendly_id;我们将关注点分开,让我们能够一次更改关注点并更新所有模型

    3. 您正在寻找class methods


    Fat Model Skinny Controller

    虽然没有很好的文档记录,但核心 Rails 模式之一是让您的控制器尽可能精简。为此,dhh 建议将大量方法放入模型(作用域、类方法等) - 让您可以简洁地调用它们

    这是一个通用的编程模式


    Inherited Resources

    我最喜欢的一个 - 这会在您的控制器中创建标准的 RESTful 操作接口,因此您不需要自己包含它:

    #app/controllers/posts_controller.rb
    class PostsController < InheritedResources::Base
    end
    

    这将自动加载indexshownewcreateeditupdatedestroy


    Callbacks

    最后,你应该注意回调

    这些允许您使用单个实例方法运行通用代码。一个很好的例子是find

    #app/controllers/posts_controller.rb
    class PostsController < ApplicationController
        before_action :load_post, only: [:show, :edit]
    
        private
        def load_post
            @post = Post.find params[:id]
        end
    end
    

    【讨论】:

      【解决方案2】:

      在这种情况下,您最好的选择可能是使用表单对象。表单对象的存在只是为了抽象出控制器中发生的复杂交互。这会产生更简洁、更可维护的代码,以及其他巨大的好处。您可以在http://pivotallabs.com/form-backing-objects-for-fun-and-profit/http://railscasts.com/episodes/416-form-objects(专业版)阅读更多内容并找到该技术的一些优秀示例,或者只需搜索“rails form objects”。

      【讨论】:

      • 如果数据处理中不涉及表格怎么办?比如解析数据馈送?
      • 在这种情况下,我应用了相同的基本原则。基本上,制作一些您可以使用的东西,例如DataFeed.parse,它会制作您的 ObjectsInFeed 和所有其他内容,这样您的控制器中实际上只有一两行。但是,您可能不想在控制器中访问数据馈送,除非您有某种限制或其他限制。您可能会从 github.com/javan/whenever 之类的东西中获得更好的里程数。
      • 实际上,我想得越多,通过数据馈送我几乎总是把它变成宝石。额外的努力通常是微不足道的,它可以通过将它们分解成相关的部分来加速你的测试套件(想想如果你用你的应用程序测试运行每个 gem 的测试)。您还可以获得能够将它重用于其他项目的优势,或者发布它并成名(除非它是一些内部 API 或其他东西)。我确定您已经拥有,但如果没有,可能值得调查一下类似的宝石是否已经存在。
      猜你喜欢
      • 2012-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-17
      • 1970-01-01
      • 2011-11-21
      • 2015-06-25
      相关资源
      最近更新 更多