我的Rails应用程序最多可以有一个管理员,但任意数量的用户。如何确保最多一个管理员在轨道应用程序设计?
我正在使用设计宝石,并且正在使用用户模型和布尔管理字段来确定用户是否为管理员。
我想确保在应用程序实例上至多存在一个管理员。更具体地说,我想确保如果网站上已存在管理员,则无法添加其他管理员。
我目前有一个弱的解决方案,覆盖用户/注册/新设计视图,只有在数据库中没有管理员(否则只有用户可以注册)的情况下允许用户注册为管理员。
<!-- in /users/registrations/new.html.erb -->
<% if admin_exists? %>
<h2>User Sign up</h2>
<% else %>
<h2>Admin Sign up</h2>
<% end %>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
...
<% unless admin_exists? %>
<%= f.hidden_field :admin, value: true%>
<% end %>
...
我需要比这更强的检查,所以我认为以下几点:
验证:我不希望使用ActiveRecord的验证,因为有验证时跳过场景,允许多个管理员将是灾难性的。
before_action:基于this方法,它向控制器添加过滤器,我可以添加一个检查,以防止在创建和更新期间添加管理员。
使用触发器和存储的特效(啊!)
更新1:
非常类似于图2,在ApplicationController中使用的检查如下:
class ApplicationController < ActionController::Base before_action :check_at_most_one_admin_on_writes, if: :devise_controller?, only: [:create, :update] private def check_at_most_one_admin_on_user_writes if(admin_exists && params.has_key?(:admin) && params[:admin] == true) flash[:alert] = "Site administrator already exists" redirect_to :back end end end
更新2: (4)不起作用。可能需要直接覆盖RegistrationsController。
我还不确定这些功能是否足够强大,足以保证两个管理员永远不会无意中创建。在多达一个管理约束下执行此操作的好方法是什么?
更新3:(基于下面的评论)
的应用程序是一个个人网站的框架,每个客户下载,部署到主控器,然后立即配置自己作为管理员。所以,我不能通过种子等预先创建管理员。
你不应该允许任何提升权限的字段(比如'role'或者'admin')可以从表单访问,使用种子创建你的admin用户,并且不允许删除它们,你可以防止删除,或保存在模型中的回调(如果由于某种原因,你故意跳过验证) – Pavling 2014-10-11 16:09:35
@Pavling谢谢。rails应用程序是一个个人网站框架,每个客户下载,部署到一个主机,然后立即配置为一个自己因此,我不能通过种子等方式预先创建管理员 – Anand 2014-10-11 16:11:54
您可以拥有一个生成管理员的rake任务...但是如果您坚持按照您的计划方式执行此任务,请拥有一个单独的控制器和路由用于创建管理员用户(与正常Devise路线分开)。您仍然可以继承Devise控制器,但在AdminsController中您可以设置admi n属性并通过将块传递给'super'来检查冲突。 – Pavling 2014-10-12 08:28:44