2016-12-01 3 views
0

О маршрутизации, если я что-то вроде этого:Rails 5 ресурсов маршрутизации с использованием пользовательских действий

resources :students 
resources :teachers 

я получить что-то вроде:

студенты GET /students(.:format) студентов # индекс
...
учителя ПОЛУЧИТЬ /teachers(.:format) учителя # индекс
...

Переход к:

resources :students, controller: :users 
resources :teachers, controller: :users 

даст мне:

студентов GET /students(.:format) пользователей # индекс
учителей GET /teachers(.:format) пользователей # индекс

Обратите внимание, что в настоящее время, как ресурсы, используя один и тот же контроллер Users и то же действие index. Но то, что мне нужно, вместо того, чтобы использовать то же самое действие index, является ресурсом students, чтобы использовать действия, предваренные students, как students_index и teachers ресурсов с префиксом teachers как teacher_index.

Другими словами, я хочу bin/rails routes дать мне следующий вывод:

студенты получают /students(.:format) пользователей # students_index
учителей овладевают /teachers(.:format) пользователей # teachers_index

Я знаю, что я могу сделать то же самое с:

get 'students', to: 'users#students_index' 

Но есть ли способ сделать то же самое с ресурсами?

+0

Возможно, вы ищете коллекцию или член – Mingsheng

+1

Почему вы не используете подклассы использования для вашего контроллера? поэтому пользователь-контроллер и подклассы ученика и учителя? если вы действительно хотите этого, вам нужно сопоставить каждое действие CURL. – Roger

+0

@Rogier как 'student', так и' teacher' являются 'пользователями'. Эти маршруты предназначены для API. Я не хочу иметь одну конечную точку, например: 'POST http: // localhost: 3000/users', чтобы создать« ученик »и« учитель ». Для этого я должен каждый раз указывать, какой тип пользователя я создаю. – psantos

ответ

0

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

resources :students, controller: :users, except: [:index] 
resources :teachers, controller: :users, except: [:index] 

то, как вы уже предложили, сделать индивиды индексные акции, как, что:

get 'students', to: 'users#students_index', as: :student 
get 'teachers', to: 'users#teachers_index', as: :teacher 

Или вы могли бы пересмотреть структуру своих контроллеров ... Удачи!

+0

Первый комментарий @Rogier дает мне представление. Я создаю 'UserController' (базовый),' TeachersController' и 'StudentsController', который наследует' UsersController' – psantos

0

Существует гораздо лучший способ сделать это, как вы могли предположить - наследование.

# app/controllers/users_controller.rb 
class UsersController < ApplicationController 

    delegate :singular, :plural, :param_key, to: :model_name 

    before_action :set_resource, only: [:show, :edit, :update, :destroy] 
    before_action :set_resources, only: [:index] 

    def initialize 
    @model_name = resource_class.model_name 
    super 
    end 

    def show 
    end 

    def index 
    end 

    def new 
    @resource = resource_class.new 
    set_resource 
    end 

    def create 
    @resource = resource_class.new(permitted_attributes) 

    if @resource.save 
     redirect_to @resource 
    else 
     set_resource 
     render :new 
    end 
    end 

    def edit 
    end 

    def update 
    if @resource.update(permitted_attributes) 
     redirect_to @resource 
    else 
     set_resource 
     render :edit 
    end 
    end 

    def destroy 
    @resource.destroy 
    redirect_to action: "index" 
    end 

    # ... 

    private 

    # Deduces the class of the model based on the controller name 
    # TeachersController would try to resolve Teacher for example. 
    def resource_class 
    @resource_class ||= controller_name.classify.constantize 
    end 

    # will set @resource as well as @teacher or @student 
    def set_resource 
    @resource ||= resource_class.find(params[:id]) 
    instance_variable_set("@#{singular}", @resource) 
    end 

    # will set @resources as well as @teachers or @students 
    def set_resources 
    @resources ||= resource_class.all 
    instance_variable_set("@#{plural}", @resources) 
    end 

    def permitted_attributes 
    params.require(param_key).permit(:a, :b, :c) 
    end 
end 

# app/controllers/teachers_controller.rb 
class TeachersController < UsersController 
end 

# app/controllers/students_controller.rb 
class StudentsController < UsersController 
end 

# routes.rb 
resources :students 
resources :teachers 

Это позволяет следовать соглашению регулярного Rails над подходом конфигурации, когда речь идет о назывании действий и взглядах.

Базовый класс UsersController использует довольно малую магию через ActiveModel::Naming как для определения класса модели, так и для того, чтобы назвать переменные экземпляра и ключи params.

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