создание контроллера оболочки для всех вызовов веб-служб в 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"
}