2016-12-01 3 views
0

Über Routing verwenden, wenn ich so etwas tun:Rails 5 Ressourcen Routing benutzerdefinierte Aktionen

resources :students 
resources :teachers 

Ich werde so etwas wie erhalten:

Studenten GET Studenten /students(.:format) # Index
...
Lehrer GET /teachers(.:format) Lehrer # Index
...

Wechsel zu:

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

wird mir geben:

Studenten /students(.:format) Benutzer # Index
Lehrer GET /teachers(.:format) Benutzer # Index GET

Beachten Sie, dass jetzt beide Ressourcen werden mit dem gleichen Controller Users und die gleiche Aktion index. Aber was ich brauche, anstatt die gleiche index Aktion zu verwenden, ist die Ressource zu Aktionen mit dem Präfix wie students_index und teachers Ressourcen mit dem Präfix teachers wie teacher_index.

Mit anderen Worten, ich bin/rails routes wollen, dass ich die folgende Ausgabe geben:

Studenten GET /students(.:format) Benutzer # students_index
Lehrer GET /teachers(.:format) Benutzer # teachers_index

ich weiß, dass ich mit das gleiche tun:

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

Aber es gibt einen Weg, das Gleiche mit Ressourcen zu tun?

+0

Wahrscheinlich für eine Sammlung oder Mitglied suchen – Mingsheng

+1

Warum verwenden Sie keine Unterklassen für Ihren Controller? so Controller Benutzer und Unterklassen Schüler und Lehrer? Wenn Sie das wirklich wollen, müssen Sie jede der CURL-Aktionen zuordnen. – Roger

+0

@Rogier "Schüler" und "Lehrer" sind "Benutzer". Diese Routen gelten für eine API. Ich möchte keinen einzigen Endpunkt haben wie: 'POST http: // localhost: 3000/users', um den' Schüler' und 'Lehrer' zu erstellen. Dazu muss ich immer angeben, welche Art von Benutzer ich erstelle. – psantos

Antwort

0

Ich glaube nicht, dass es eine Möglichkeit gibt, das mit Ressourcenhelfer zu tun. Was Sie tun können (wenn es nur der Index Aktion ist, Sie wollen Überschreibung) ist hinzuzufügen eine Ausnahme, wie folgt aus:

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

dann, wie Sie bereits angedeutet, tun die Individuen Index Aktionen wie folgt aus:

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

Oder Sie könnten die Struktur Ihrer Controller überdenken ... Viel Glück!

+0

Der erste @ Rogier-Kommentar gibt mir einen Einblick. Ich erstelle einen 'UsersController' (Basis),' TeachersController' und 'StudentsController', der' UsersController' erbt – psantos

0

Es gibt eine viel bessere Möglichkeit, dies zu tun, wie Sie vielleicht vermutet haben - Vererbung.

# 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 

Auf diese Weise können Sie den regulären Rails Konvention über Konfiguration Ansatz folgen, wenn es um die Benennung Aktionen und Ansichten kommt.

Die UsersController-Basisklasse verwendet ziemlich viel Magie durch ActiveModel::Naming beide, um die Modellklasse und Sachen wie die Instanzvariablen und die Parameterschlüssel zu nennen.

Verwandte Themen