Хобрук: Ваш путь к мастерству в программировании

Rails Routes — динамический выбор контроллера

Допустим, ради вопроса, что у меня есть два типа пользователей: type1 и type2. Я хочу, чтобы Rails использовал контроллер/модуль в зависимости от типа отображаемого пользователя. Например:

Если у User(id: 1, type: 'type1') есть type1, а у User(id: 2, type: 'type2') есть type2, переходим к:

/users/1

выберет Type1::UsersController. И собираюсь:

/users/2

выберет Type2::UsersController.

Это позволит мне использовать разные контроллеры и представления для каждого типа.

Примечание. Я не хочу, чтобы type отображался в URL-адресе, я хочу, чтобы он был динамическим.


Ответы:


1

Как говорит GoGoCarl, на самом деле это не Rails-способ делать вещи. Тем не менее, заставить его работать не так уж и сложно. Вы можете сделать что-то подобное в routes.rb:

get 'users/:id', to: 'type1/users#show', constraints: lambda { |request| 
  _id = request.fullpath.gsub('/users/','').to_i
  # Note: there might be an easier way to get ID from the request object
  User.find(_id)._type == 'type1'
}
get 'users/:id', to: 'type2/users#show', constraints: lambda { |request| 
  _id = request.fullpath.gsub('/users/','').to_i
  User.find(_id)._type == 'type2'
}

В моем примере я переименовал ваше поле type в _type (поскольку Rails использует type для наследования одной таблицы). Я проверил это, и он работает так, как хотелось бы.

05.07.2013
  • User.find(:id) может работать (не проверено). Это похоже на возможный взлом, мне нужно его еще проверить. Спасибо за помощь. 06.07.2013
  • User.find(:id) не работает: я пробовал, хотя это и не имеет смысла. 06.07.2013

  • 2

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

    Чтобы ответить на ваш вопрос (потому что я ненавижу, когда люди оставляют рекомендации вместо ответов), вам нужно создать модуль, который расширяет маршрутизацию, что позволит вам выполнять настраиваемое сопоставление. Оттуда вы можете делать свои проверки и маршрутизировать соответствующим образом. Вот пример< /а>.

    Тем не менее, лучшим путем (без каламбура) было бы иметь один контроллер с централизованным методом, который может выбирать представления.

    def find_view view_name
      "#{view_name}#{@user.type}"
    end
    

    Таким образом, вызов render find_view('new') попытается отобразить представление с именем "new-type1". В это представление можно поместить всю пользовательскую логику type1. То же самое для пользователя type2.

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

    Как только вы поймете, что у вас есть один контроллер, есть несколько простых способов, с помощью которых вы можете отправить код, специфичный для типа пользователя, на разные пути — метод представлений, описанный выше, вы можете отправить весь свой соответствующий код отдельным помощникам. которые динамически вызываются в зависимости от типа пользователя, и я уверен, что их больше (возможно, и лучше). Но все они имеют одну важную общую черту: вы будете НАМНОГО меньше бороться с Rails и у вас будет меньше дублированного кода, если вы позволите Rails добиться своего с одним маршрутом, одним контроллером.

    Удачи, надеюсь поможет.

    05.07.2013
    Новые материалы

    Решения DBA Metrix
    DBA Metrix Solutions предоставляет удаленного администратора базы данных (DBA), который несет ответственность за внедрение, обслуживание, настройку, восстановление базы данных, а также другие..

    Начало работы с Блум
    Обзор и Codelab для генерации текста с помощью Bloom Оглавление Что такое Блум? Некоторые предостережения Настройка среды Скачивание предварительно обученного токенизатора и модели..

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

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