在 Rails 中,如何拥有 /admin 部分,然后在管理部分中拥有控制器?

问题描述 投票:0回答:7

我想在我的应用程序中有一个 /admin 部分,并在此 /admin 部分中有路由,例如:

www.example.com/admin/(只有某些用户有权访问此部分)

然后在该部分添加控制器,例如:

/admin/users/{add, new, etc}

对于这样的事情我有什么选择? (使用导轨3)

ruby-on-rails
7个回答
44
投票

我更喜欢做与托德的回答类似但略有不同的事情。与其将 before_filter 添加到与管理内容相关的每个控制器,我更喜欢创建一个 AdminController,所有与管理操作相关的控制器都可以从中继承:

# config/routes.rb
namespace :admin do
  resources :users
end

# app/controllers/admin_controller.rb
class AdminController < ApplicationController
  before_filter :authorized?
  private
  def authorized?
    unless current_user.has_role? :admin
      flash[:error] = "You are not authorized to view that page."
      redirect_to root_path
    end
  end
end

# app/controllers/admin/users_controller.rb
class Admin::UsersController < AdminController
   ...
end

18
投票

在你的routes.rb中做类似的事情:

  namespace :admin do
    resources :users
  end

请参阅 http://guides.rubyonrails.org/routing.html 了解更多详情。

然后在每个管理控制器中,您将需要一个 before_filter:

before_filter :authorized?
def authorized?
    #check if authorized here.
end

9
投票

正如托德提到的,您想要添加命名空间路由:

namespace :admin do
  resources :users
end

您还需要将控制器、视图等放入每个部分的子文件夹中,称为“admin/”。 如果您从头开始生成它,这很容易:

rails g controller admin/users

这可能看起来相当复杂,但我有一篇文章介绍了所有这些内容,其中包含一个示例 Rails 3 应用程序,您可以下载来使用它:

Ruby on Rails 3 中的路由


6
投票

然后在每个管理控制器中,您需要一个 before_filter:

before_filter :authorized?
def authorized?
  #check if authorized here.
end

我认为如果他把这段代码放到一个继承自ApplicationController的主AdminController中会更好,那么每个管理控制器都会继承这个AdminController。

关于Rails3,这里是一篇关于路线的好文章


3
投票

显然托德所说的是正确的。但是,如果您喜欢通过隐藏来提高安全性,您还可以保留

new_admin_user
url 帮助程序和
Admin::
命名空间控制器,但提供一个不太广泛使用的公共 url 路径,其中包含以下内容:

scope  :module => "admin", :as => 'admin', :path => 'xyz' do
 resources :user
end

A

rake route
使用该设置将显示沿这些线的路线:

new_admin_user GET  /xyz/users/new(.:format)  {:controller=>"admin/users", :action=>"new"}

我想唯一能阻止的攻击者是一个不成熟的攻击者,他爬行并编译了一堆在

admin/
提供系统访问的 Rails 站点,但我认为敢于与管理控制台路径不同并没有什么坏处.


2
投票
application_controller.rb   
before_filter :if_namespace_is_admin?

def if_name_space_is_admin?
    #now you should check to see if the namespace is from admin
    #now you need namespaces because ruby ns confuse the f'out of me
end 

0
投票

当您在子文件夹中组织控制器时,您必须在控制器顶部添加模块行以匹配“命名空间”。例如,在我的例子中,我希望管理员用户管理制造商,它位于下一个文件夹中: /应用程序/控制器/用户/管理员

然后我有一个控制器继承了基本控制器的遗产,如下所示:

module Users::Admin
  class Users::Admin::AdminController < ApplicationController
    before_action :authenticate_admin!
    private
    def authenticate_admin!
      unless current_user&.is_admin?
        redirect_to root_path, alert: 'You are not authorized to access this page'
      end
    end
  end
end

同样位于/app/controllers/users/admin文件夹中的manufacturer_controller以这种方式启动:

module Users::Admin
  class Users::Admin::ManufacturersController < AdminController
    before_action :set_manufacturer, only: %i[show edit update]
    include Pagy::Backend

    @is_new = true
    @some_text = 'Hello World'

    def index
      # @manufacturers = current_user.manufacturers
      @q = current_user.manufacturers.ransack(params[:q])
      @q.sorts = 'name asc' if @q.sorts.empty?
      @pagy, @manufacturers = pagy(@q.result(distinct: true), items: 25)
    end
....
© www.soinside.com 2019 - 2024. All rights reserved.