2017-02-21 100 views
10

Я работаю над созданием оболочки для существующих контроллеров приложений.создать контроллер оболочки для всех вызовов веб-сервисов в 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

Любая помощь будет оценена. Заранее спасибо.

+0

Есть ли конкретная причина, по которой вы хотите/должны это сделать? – Iceman

+0

Helle Iceman, спасибо за ваш ответ, я хочу выставить общий API для возврата списка или реализовать другие функции –

+1

Я не рекомендую общий контроллер ... это рецепт кошмара абстракций, или вы закончите с много условий IF увеличивает сложность действий, чтобы не повторять их, поскольку они, вероятно, не делают точно то же самое на каждой панели, используется ... Здесь вы можете увидеть сообщение о предмете абстракции ... https : //www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction – cefigueiredo

ответ

3

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

В любом случае, возможно, вам лучше организовать вашу бизнес-логику внутри приложения Rails. В качестве отправной точки я настоятельно рекомендую прочитать this article. Основываясь на ограниченной информации из вашего вопроса, трудно дать хороший ответ для вашего конкретного случая.

Например, вы можете реализовать объект запроса:

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 к EmployeeController и /department/list к DepartmentController. И в основном это направит на любой действительный контроллер, так что, возможно, вы хотите немного его настроить и добавить некоторые ограничения.

Надеюсь, что это поможет. Приветствия.

+0

Спасибо, это именно то, что я сделал –

-1

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

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" 
    } 
+0

Привет, Эссе, спасибо за ваш ответ. Что делать, если в дополнение к Employee, Department есть n количество нескольких контроллеров. Это стандартный подход? можете ли вы указать мне на документацию. –

+0

вот документация: http://guides.rubyonrails.org/routing.html#request-based-constraints, если вам нужно предоставить несколько таких контроллеров, я бы рекомендовал создать объект ограничения и переместить туда эту логику. И проверить его, конечно;) – Esse

0

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

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 
0

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^