Rails 7中如何仅为路由(含resources)设置命名空间且不改动模型控制器
解决方法
要给resources路由添加命名空间前缀(路径和路由名称),同时不修改模型、控制器,仅调整视图路径,别用namespace块(它会强制查找命名空间下的控制器),改用scope块配合模板默认值即可实现:
1. 基础路由配置
在config/routes.rb里用scope设置路径前缀和路由名称前缀,同时指定module: false确保Rails使用根目录下的原有控制器,再给每个resources的动作绑定对应命名空间的视图模板:
scope '/admin', as: 'admin', module: false do resources :posts do # 集合动作 collection do get :index, defaults: { template: 'admin/posts/index' } post :create, defaults: { template: 'admin/posts/create' } end # 成员动作 member do get :show, defaults: { template: 'admin/posts/show' } get :edit, defaults: { template: 'admin/posts/edit' } patch :update, defaults: { template: 'admin/posts/update' } put :update, defaults: { template: 'admin/posts/update' } delete :destroy, defaults: { template: 'admin/posts/destroy' } end # new动作 get :new, on: :collection, defaults: { template: 'admin/posts/new' } end end
2. 视图文件调整
把原来app/views/posts/下的所有视图文件,移动到app/views/admin/posts/目录里,保持文件名不变即可。
3. 批量处理多个resources
如果要给多个资源加相同的命名空间,用循环批量配置更高效:
scope '/admin', as: 'admin', module: false do # 把需要处理的资源名称都放在这里 [:posts, :comments, :users].each do |resource| resources resource do # 处理集合动作 %w[index create].each do |action| if action == 'index' get action, defaults: { template: "admin/#{resource}/#{action}" } else post action, defaults: { template: "admin/#{resource}/#{action}" } end end # 处理成员动作 %w[show edit update destroy].each do |action| case action when 'show', 'edit' get action, defaults: { template: "admin/#{resource}/#{action}" } when 'update' patch action, defaults: { template: "admin/#{resource}/#{action}" } put action, defaults: { template: "admin/#{resource}/#{action}" } else delete action, defaults: { template: "admin/#{resource}/#{action}" } end end # 处理new动作 get :new, on: :collection, defaults: { template: "admin/#{resource}/new" } end end end
这样配置后,路由会带上/admin前缀(比如/admin/posts),路由名称也会加上admin_前缀(比如admin_posts_path),控制器还是用原来的PostsController,视图自动加载admin/posts目录下的文件,完全不用修改模型和控制器代码。
内容的提问来源于stack exchange,提问作者onedumbquestion
相关产品推荐
相关产品推荐

