создание контроллера оболочки для всех вызовов веб-служб в rails

Я работаю над созданием оболочки для существующих контроллеров приложений.

например, у меня есть два контроллера принимает такой же набор параметров и аналогичные методы.

код, как показано ниже

class EmployeeController < ApplicationController

  def list
  end

end


class DepartmentController < ApplicationController

  def list
  end

end

конечная точка будет 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

конечная точка будет http://localhost:3000/wrapper/list

любая помощь будет оценили. Спасибо заранее.

4 ответов


этой WrapperController звучит как очень плохая идея. Особенно создание экземпляра другого контроллера и вызов метода на нем. Не припомню, чтобы где-нибудь видел такую картину. Rails делает много магии вокруг цикла запроса/ответа, поэтому вызов другого контроллера, скорее всего, сломает что-то позже. Я просто предполагаю, что cookies могут не работать, или рендеринг может быть сломан и т. д.

в любом случае, что вы, вероятно, хотите лучше организовать бизнес-логику внутри приложения 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

теперь вы можете создать 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

и config/routes.rb:

get "/:which/list" => "lists#index"

это может быть впоследствии расширена с большим количеством ресурсов и отдельных объектов запроса для каждого сделает его более ремонтопригодный. Единственная проблема заключается в том, как визуализировать сгенерированные результаты, но вы можете использовать аналогичный шаблон для выбора правильного шаблона для рендеринга.

если вы хотите иметь аналогичный шаблон для создания объектов, вы должны посмотреть шаблон объекта службы. Это описано в связанной статье.

также вы можете решить свою проблему гораздо более простым способом, просто изменив config/routes.rb немного.

get "/:controller/list", to: :list

он будет по маршруту /employee/list to EmployeeController и /department/list to DepartmentController. И в основном это будет маршрут к любому действительному контроллеру, поэтому, возможно, вы хотите немного настроить его и добавить некоторые ограничения.

надеюсь, это поможет. Овации.


почему бы нам просто не переслать его с тем же запросом

class WrapperController < ApplicationController


  def list
    if params["which"].eql?("employee")
      controller = EmployeeController.new
    else
      controller = DepartmentController.new
    end
    controller.request = request
    controller.response = response
    controller.list

  end
end

У вас уже есть это с контроллером приложения, поэтому его Родительский контроллер. Стандартным способом было бы добавить before_action в ApplicationController, который выполняет проверку, а затем перенаправляет на соответствующий контроллер.

class ApplicationController

    before_action :check_emp_or_dept

    def check_emp_or_dept
        if employee_params.fetch("which", "").eql?("employee")
            @employee = Employee.find employee_params['id'] 
            redirect_to @employee
        else
            @department = Department.find department_params['id']
            redirect_to @department
        end
    end

  protected
    # handle strong params according to what your model requires
    def department_params
      params.require(:department).permit(:param1, :param2)
    end

    # handle strong params according to what your model requires
    def employee_params
        params.require(:department).permit(:param1, :param2)
    end

end

обратите внимание, что этот код выше необходимо будет переработать для вашей конкретной настройки для сильных параметров. Я бы сказал, что это не очень хорошая идея создавать сотрудников/отделы вслепую на основе переданных параметров, хотя вы можете легко изменить методы поиска выше для методов "find_or_create_by", если вы так выбираете.


Вы можете сделать это легко в маршрутизации (т. е. routes.rb file) использование ограничений:

get '/wrapper/list', to: 'employee#list', 
  constraints: lambda { |request| 
    request.query_parameters["which"] == "employee"
  }
get '/wrapper/list', to: 'department#list', 
  constraints: lambda { |request|
    request.query_parameters["which"] != "employee"
  }