【问题标题】:App with Accounts and Users - Devise user can't create additional users具有帐户和用户的应用程序 - 设计用户无法创建其他用户
【发布时间】:2012-02-02 19:56:43
【问题描述】:

将 Rails 3.1.3 与 Devise 1.5.3 结合使用。我的应用程序有帐户和用户。每个帐户可以有多个用户。一个用户可以有一个角色,“user”或“account_admin”。设计signup 路由到accounts#new。帐户和初始 account_admin 用户是同时创建的。按照here 的描述得到了这个工作(尽管从那时起事情已经发展了一些)。

account_admin 标志应该能够在该帐户中创建其他用户。这就是我遇到麻烦的地方:它不是创建新用户,而是重定向到 user_path (users#show) 页面,并显示消息“您已经登录”。 (user_path 是我覆盖的 after_sign_in_path。)

这个article 提出了类似的问题。答案建议为管理员使用单独的命名空间,但由于管理员是我常规应用程序的一部分,我认为这不适用。

我已经定义了一个完整的用户控制器。根据日志,GET "/users/new" 从我的“UsersController#new”渲染。但是 POST "/users" 被 Devise 拦截并从“Devise::RegistrationsController#create”渲染。

config/routes.rb

devise_for :users
devise_scope :user do
  get "signup",   :to => "accounts#new"
  get "signin",   :to => "devise/sessions#new"
  get "signout",  :to => "devise/sessions#destroy"
end
resources :users
resources :accounts

app/controllers/users_controller.rb

class UsersController < ApplicationController
  before_filter :authenticate_user!
  load_and_authorize_resource # CanCan
  ...
  def new
    # CanCan:  @user = User.new
  end

  def create
    # CanCan:  @user = User.new(params[:user])
    @user.skip_confirmation! # confirm immediately--don't require email confirmation
    if @user.save
      flash[:success] = "User added and activated."
      redirect_to users_path # list of all users
    else
      render 'new'
    end
  end
  ...
end    

我尝试过overriding the Devise controller,我想如果用户已经登录,我可以告诉它使用我的users#create 操作。日志告诉我它正在使用我的控制器(“由 RegistrationsController 处理#create as HTML” ),但它似乎没有执行它的代码。我已经注释掉了我的自定义操作,只是留在了记录器行中,但我没有收到我的记录消息。尽管super 被注释掉了,但行为并没有改变——它仍然会重定向为“您已经登录”。

config/routes.rb

devise_for :users, :controllers =&gt; {:registrations =&gt; "registrations"}

app/controllers/registrations_controller.rb

class RegistrationsController < Devise::RegistrationsController
  def new
    logger.info "Custom RegistrationsController:  new"
    super
  end

  def create
    logger.info "Custom RegistrationsController:  create"
#    super unless user_signed_in?
#    render "users#create"
  end

  def update
    super
  end
end 

我错过了什么?如何让 account_admin 用户创建其他用户?

【问题讨论】:

    标签: ruby-on-rails-3.1 devise


    【解决方案1】:

    主要问题是 Devise 拦截了 POST "/users"(以及其他一些路线)。找到此解决方法以允许我的用户控制器处理这些路由:更改 devise_for 以跳过注册,然后添加回 Devise 通常为其定义别名的路由:

    routes.rb

    devise_for :users, :skip => [:registrations]
    devise_scope :user do
      get "signup",   :to => "accounts#new"
      get "signin",   :to => "devise/sessions#new"
      get "signout",  :to => "devise/sessions#destroy"
      get "cancel_user_registration", :to => "devise/registrations#cancel"
      post "user_registration",       :to => "users#create"
      get "new_user_registration",    :to => "accounts#new"
      get "edit_user_registration",   :to => "users#edit"
    end
    resources :users
    resources :accounts
    

    从来没有弄清楚为什么设计控制器覆盖不起作用。

    this thread 上的用户指出 devise_invitable gem 可能是一个有趣的替代方案。

    【讨论】:

      【解决方案2】:

      这就是我最终将它与我的设置一起使用的方式(设计绑定到我的用户模型——没有单独的编辑器/管理模型):

      class UsermakersController < ApplicationController
      before_action :authenticate_user!
      
      def new
          @user = User.new
      end
      
      def create
          @user = User.new(user_params)
      
          respond_to do |format|
            if @user.save
              format.html { redirect_to users_path, notice: 'User was successfully created.' }
              format.json { render :show, status: :created, location: @user }
            else
              format.html { render users_path }
              format.json { render json: @user.errors, status: :unprocessable_entity }
            end
          end
      end
      
      private
          def user_params
            userParams = params.require(:user).permit(:name, :email)
          end
      end
      

      从这里开始,当您想将新用户添加为另一个用户时,只需在表单中调用 Usermakers#new url,例如,我在用户索引页面的底部有这个:

       <%= link_to 'Add User', new_usermaker_path, id: 'new_user_link' %>
      

      Usermakers 表单如下所示:

      = simple_form_for @user, url: usermakers_path, html: {multipart: true} do |f|
      =f.error_notification errors: true
      
      = f.input :name
      = f.input :email
      
      %p
      = f.button :submit, 'Create User', class: 'button'
      

      当然,您需要添加一个虚拟的 new.html.erb 文件,该文件只是呈现 _form.html.erb 以使用它。

      只需将 new 和 create 方法添加到您的 routes.rb 文件(无论是通过 resources :usermakers 还是更具体的路由),您就可以开始了。希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2012-12-18
        • 1970-01-01
        • 1970-01-01
        • 2021-03-09
        • 2018-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多