【问题标题】:Best Practices for reusing code between controllers in Ruby on Rails在 Ruby on Rails 中的控制器之间重用代码的最佳实践
【发布时间】:2010-09-12 19:25:03
【问题描述】:

我想分享一些控制器方法。在 ruby​​ on rails 中执行此操作的最佳实践是什么?我应该创建一个我的控制器扩展的抽象类,还是应该创建模块并将其添加到每个控制器中?下面是我要分享的控制器方法:

def driving_directions
  @address_to = params[:address_to]
  @address_from = params[:address_from]
  @map_center = params[:map_center_start]

  # if we were not given a center point to start our map on
  # let's create one.
  if !@map_center && @address_to
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_to).ll
  elsif !@map_center && @address_from
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_from).ll
  end
end

def printer_friendly
  starting_point = params[:starting_point].split(',').collect{|e|e.to_f}
  ne = params[:ne].split(',').collect{|e|e.to_f}
  sw = params[:sw].split(',').collect{|e|e.to_f}
  size = params[:size].split(',').collect{|e|e.to_f}
  address = params[:address]

  @markers = retrieve_points(ne,sw,size,false)
  @map = initialize_map([[sw[0],sw[1]],[ne[0],ne[1]]],[starting_point[0],starting_point[1]],false,@markers,true)
  @address_string = address
end

【问题讨论】:

  • 在这种情况下不使用 application.rb 是否有特殊原因?
  • 只有部分控制器会使用代码,但不是全部。

标签: ruby-on-rails ruby


【解决方案1】:

我实际上认为模块是在控制器之间共享代码的最佳方式。如果您想在视图之间共享代码,助手是很好的。 Helpers 基本上是美化的模块,所以如果您不需要视图级别的访问权限,我建议在您的 lib 文件夹中放置一个模块。

创建模块后,您必须使用 include 语句将其包含在所需的控制器中。

http://www.rubyist.net/~slagell/ruby/modules.html

【讨论】:

    【解决方案2】:

    我同意模块方法。在您的 lib 目录中创建一个单独的 Ruby 文件并将模块放入新文件中。

    最明显的方法是将方法添加到您的 ApplicationController,但我相信您已经知道了。

    【讨论】:

      【解决方案3】:

      在我看来,正常的 OO 设计原则适用:

      • 如果代码确实是一组不需要访问对象状态的实用程序,我会考虑将它放在一个模块中单独调用。例如,如果代码都是映射实用程序,则创建一个模块 Maps,并访问如下方法:Maps::driving_directions
      • 如果代码需要状态并且在每个控制器中使用或可以使用,请将代码放在 ApplicationController 中。
      • 如果代码需要状态并用于所有逻辑密切相关的控制器的子集(即所有关于地图),则创建一个基类 (class MapController < ApplicationController) 并将共享代码放在那里。
      • 如果代码需要状态并且用于所有不密切相关的控制器的子集中,请将其放入模块中并将其包含在必要的控制器中。

      在您的情况下,方法需要状态 (params),因此选择取决于需要它的控制器之间的逻辑关系。 另外:

      还有:

      • 在可能的情况下使用部分代码来处理重复代码,并将其放置在通用的“部分”目录中或通过特定路径包含。
      • 尽可能坚持使用 RESTful 方法(对于方法),如果您发现自己创建了很多非 RESTful 方法,请考虑将它们提取到自己的控制器中。

      【讨论】:

        【解决方案4】:

        另一种可能性:

        如果您的公共代码需要状态并且您想在控制器之间共享行为,您可以将它放在 modellib 目录中的普通旧 ruby​​ 类中。请记住,model 类不必是持久的,即使所有 ActiveRecord 类都是持久的。换句话说,拥有瞬态model 类是可以接受的。

        【讨论】:

          【解决方案5】:

          如果你想在控制器和助手之间共享代码,那么你应该尝试在库中创建一个模块。您也可以使用@template 和@controller 来访问控制器和助手中的方法。 检查此以获取更多详细信息http://www.shanison.com/?p=305

          【讨论】:

            【解决方案6】:

            我知道这个问题是 6 年前提出的。只想指出,在 Rails 4 中,现在有控制器问题,这是一种开箱即用的解决方案。

            【讨论】:

              【解决方案7】:

              我发现在控制器之间共享相同代码的一种有效方法是让一个控制器从另一个控制器(代码所在的位置)继承。我使用这种方法将控制器中定义的相同方法与另一组命名空间控制器共享。

              【讨论】:

              猜你喜欢
              • 2012-08-12
              • 2017-06-20
              • 1970-01-01
              • 2010-09-27
              • 2011-08-02
              • 2014-08-16
              • 1970-01-01
              • 2010-09-08
              • 1970-01-01
              相关资源
              最近更新 更多