在 Rails 5.1 中从管理命名空间创建设计用户

Create Devise User from Admin Namespace in Rails 5.1

我的应用程序中有一个用于自定义仪表板的 admin 命名空间路由。我至少有 8 个模型在工作,并且没有错误的 crud 操作——除了一个。我正在使用 Devise Gem 进行用户管理和用户模型。我在管理命名空间中有 User 模型,我可以开始工作的唯一操作是更改角色和销毁,但我无法从仪表板创建新用户。当我尝试创建一个新用户时;我收到错误 "You are already signed in.".

controllers/admin/users_controller.rb

class Admin::UsersController < ApplicationController
  before_action :authenticate_user!
  before_action :admin_only, :except => :show

  def index
    @users = User.all
  end

  def show
    @user = User.find(params[:id])
    unless current_user.admin?
      unless @user == current_user
        redirect_to root_path, :alert => 'Access denied.'
      end
    end
  end

  def create
    @user = User.new
  end

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(secure_params)
      redirect_to users_path, :notice => 'User updated.'
    else
      redirect_to admin_users_path, :alert => 'Unable to update user.'
    end
  end

  def destroy
    @user = User.find(params[:id])
    user.destroy
    redirect_to admin_users_path, :notice => 'User deleted.'
  end

  private

  def admin_only
    unless current_user.admin?
      redirect_to root_path, :alert => 'Access denied.'
    end
  end

  def secure_params
    params.require(:user).permit!
  end

end

models/user.rb

class User < ApplicationRecord
  enum role: [:user, :admin]

  def set_default_role
    self.role ||= :user
  end

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

views/admin/users/new.html.erb

<%= form_for User.new do |f| %>
  <div class="form-group">
    <%= f.label :first_name %><br/>
    <%= f.text_field :first_name, autofocus: true %>
  </div>
  <div class="form-group">
    <%= f.label :last_name %><br/>
    <%= f.text_field :last_name %>
  </div>
  <div class="form-group">
    <%= f.label :email %><br/>
    <%= f.email_field :email %>
  </div>
  <div class="form-group">
    <%= f.label :password %>
    <% if @minimum_password_length %>
        <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br/>
    <%= f.password_field :password, autocomplete: "off" %>
  </div>
  <div class="from-group">
    <%= f.label :password_confirmation %><br/>
    <%= f.password_field :password_confirmation, autocomplete: "off" %>
  </div>
  <div class="form-group" style="margin-top: 1em">
    <%= f.submit 'Sign up', class: 'btn btn--primary type--uppercase inner-link'  %>
  </div>
<% end %>

views/admin/users/new.html.erb(其他方法)

<%= form_for([:admin, @user]) do |f| %>

这就是我所有名称间隔形式的设置方式,但这给了我错误 First argument in form cannot contain nil or be empty

routes.rb

...
namespace :admin do
  get '', to: 'dashboard#index', as: '/'
  resources :pages
  resources :articles
  resources :categories
  resources :tags
  devise_for :users
  resources :users
  resources :albums
  resources :banners

  resources :products do
    resources :variations
  end
end
...

使用 registration#create 操作是否适合此架构?

因为该操作建立在不同的概念上,即用户未登录并且对此进行了一系列检查。

views/admin/users/new.html.erb

您正在使用 registration#new 控制器操作,它没有 @admin 稳定。

def new
   @admin = Admin.find(params[:admin_id])
   ....
end

这就是你得到错误的原因,而且这种方法也不正确。 用户需要在传统设计路由器上注册,然后您还必须为管理员创建一个嵌套路由器来创建新用户。

这是你给管理员用户 link registration#new 您当前的 view/controller#action 具有 @admin = Admin.find(params[:id]) 价值并且视图具有以下 link

link_to new_admin_user_path(:admin, :user)

new_admin_user_path 用于您在嵌套路由中定义的 url /admin/:admin_id/users/sign_up(.:format)

步骤 2) 决定使用哪个 controller#action

您要使用标准 users/registrations#create 还是为此使用新操作?

我认为您应该按照 devise guide

中所述,通过在您的应用中生成控制器操作来增强 users/registrations#create

然后在设计控制器中registrations

def new 
   @admin = Admin.new(:params[:admin_id]) if params[:admin_id].present?
end

你的 registrations#new#create 仍然会触发错误,你将不得不阅读设计如何通过阅读他们的 amazing sourcecode and rdoc documentation 来创建这个用户,相应地修改过程以便 admins 可以通过使用 action 创建 users 否则 less DRY 替代方法是创建一个新的 controller#action 并使用它来调用现有的 User 方法或您将在 User 模型中创建的方法来创建用户。最后,User 只是您的 users 数据库 table 中的一个条目。只是以与其他用户类似的方式创建。由于管理员正在创建临时密码,因此 encryption/security 问题不再那么重要。 User 无论如何都必须更改密码。