[英]Rails 5 routing resources using custom actions
关于路由,如果我做这样的事情:
resources :students
resources :teachers
我会得到类似:
学生GET /学生(。:format)学生#index
...
教师GET /teachers(.:format)教师#index
...
更改为:
resources :students, controller: :users
resources :teachers, controller: :users
会给我:
学生GET /students(.:format)users#index
教师GET /teachers(.:format)users#index
请注意,现在,两个资源都使用相同的控制器Users
和相同的操作index
。 但是,我需要的不是使用相同的index
动作,而是使用students
资源来使用以students
为前缀的动作(如students_index
和以teachers
为前缀的teachers
资源(如teacher_index
。
换句话说,我希望bin/rails routes
能够提供以下输出:
学生GET /students(.:format)users#students_index
教师GET /teachers(.:format)users#teachers_index
我知道我可以使用以下方法进行操作:
get 'students', to: 'users#students_index'
但是有一种方法可以对资源进行处理吗?
我认为没有办法使用资源助手来做到这一点。 您可以执行的操作(如果仅是您要覆盖的索引操作)是添加一个例外,如下所示:
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
或者您可以重新考虑控制器的结构...祝您好运!
有一种更好的方法可以做到这一点,因为您可能已经猜到了-继承。
# 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键之类的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.