为rails中的所有Web服务调用创建一个包装器控制器

ope*_*per 10 design-patterns ruby-on-rails

我正在为现有的应用程序控制器创建一个包装器.

例如,我有两个控制器接受类似的参数集和类似的方法.

代码如下

class EmployeeController < ApplicationController

  def list
  end

end


class DepartmentController < ApplicationController

  def list
  end

end
Run Code Online (Sandbox Code Playgroud)

终点是http:// localhost:3000/employee/list & http:// localhost:3000/department/list

创建包装器控制器和调用任一控制器操作的最佳方法是什么.

这是正确的,我们检查某些参数并相应地创建对象,或者有更好的方法来做到这一点

class WrapperController < ApplicationController


  def list
    if params["which"].eql?("employee")
      data = EmployeeController.new(params).create
    else
      data = DepartmentController.new(params).label
    end

  end
end
Run Code Online (Sandbox Code Playgroud)

终点是http:// localhost:3000/wrapper/list

任何帮助,将不胜感激.提前致谢.

Mic*_*iak 3

WrapperController听起来真是个糟糕的主意。特别是实例化另一个控制器并调用它的方法。我不记得在任何地方见过这样的图案。Rails 在请求/响应周期方面做了很多魔法,因此调用另一个控制器很可能会在以后破坏某些东西。我只是猜测 cookie 可能不起作用,或者渲染可能会被破坏等等。

不管怎样,您可能想要的是更好地组织 Rails 应用程序内的业务逻辑。作为起点,我强烈建议阅读这篇文章。根据您问题中的有限信息,很难针对您的具体情况给出一个好的答案。

例如,您可以实现一个查询对象:

class EmployeesQuery
  def initialize(params)
    # initialize some internal variables
  end

  def list
    # write code for fetching employees based on passed params
  end
end

class DepartmentsQuery
  def initialize(params)
    # initialize some internal variables
  end

  def list
    # write code for fetching employees based on passed params
  end
end

class QueryFactory
  QUERIES = {
    "employee" => EmployeeQuery,
    "department" => DepartmentQuery
  }

  get self.get_query(resource)
    QUERIES[resource] || raise("Some exception")
  end
end
Run Code Online (Sandbox Code Playgroud)

现在您可以创建一个ListsController

class ListsController < ApplicationController
  def index
    data = QueryFactory.get_query(params[:which]).list
    # render specific view based on requested resource
    # and rescue possible exception from get_query method
  end
end
Run Code Online (Sandbox Code Playgroud)

并在config/routes.rb

get "/:which/list" => "lists#index"
Run Code Online (Sandbox Code Playgroud)

稍后可以使用更多资源进行扩展,并且为每个资源拥有单独的查询对象将使其更易于维护。唯一的问题是如何渲染生成的结果,但您可以使用类似的模式来选择正确的模板进行渲染。

如果您想使用类似的模式来创建对象,您应该查看服务对象模式。链接文章中对此进行了描述。

您也可以用更简单的方法解决您的问题,只需config/routes.rb稍微改变一下即可。

get "/:controller/list", to: :list
Run Code Online (Sandbox Code Playgroud)

它将路由/employee/listEmployeeController/department/listDepartmentController。基本上它会路由到任何有效的控制器,所以也许你想稍微调整一下并添加一些限制。

希望有帮助。干杯。