現在、私のユーザーデータベースには、ブール値とデフォルトがfalseに設定された「admin」という列があります。 1人の管理者ユーザーがデータベースにシードされています。
are管理者であるユーザーは新しいユーザーを作成できますが、notであるユーザーは作成できないように、アプリケーションを作成するにはどうすればよいですか? (また、ユーザーは管理者によって作成される必要がありますのみ)
外部モジュールの使用を伴わない工夫でこれを行う簡単な方法があるはずのようです。しかし、これまでのところ、満足のいく答えを見つけることができませんでした。
考案のみの解決策をマークする可能性が高くなります。 (単に標準のMVC/Railsソリューションがプラスであるもの)ただし、CanCanIを使用しないより良い方法が本当にある場合 五月 それも受け入れてください。
注:
私はしばらく探し回っていましたが、これに非常によく似たスタックオーバーフローの質問が他にもいくつか見つかりましたが、質問に完全に答えていないか、他のデバイス以外のモジュールを使用しています。 (または両方)
認証を実装するには、コントローラーのメソッドを使用します
@ diego.greyrobotによって提案されたとおりです
class UsersController < ApplicationController
before_filter :authorize_admin, only: :create
def create
# admins only
end
private
# This should probably be abstracted to ApplicationController
# as shown by diego.greyrobot
def authorize_admin
return unless !current_user.admin?
redirect_to root_path, alert: 'Admins only!'
end
end
Deviseの「すでにログインしている」問題を回避するには、ユーザーを作成するための新しいルートを定義します。
ユーザーの作成を処理するための新しいルートを定義し、フォームがその場所を指すようにするだけです。このように、フォームの送信はデバイスコントローラを通過しないため、通常のRailsの方法で、どこでも自由に使用できます。
# routes.rb
Rails.application.routes.draw do
devise_for :users
resources :users, except: :create
# Name it however you want
post 'create_user' => 'users#create', as: :create_user
end
# users/new.html.erb
# notice the url argument
<%= form_for User.new, url: create_user_path do |f| %>
# The form content
<% end %>
問題は概念的なものです。 Deviseは認証ライブラリであり、承認ライブラリではありません。これを個別に実装するか、CanCanを使用する必要があります。ただし、役割が1つしかないため、これを実装するのは簡単ではありません。
Beforeフィルターを使用して、ユーザーの作成/更新/破棄アクションを保護します。
class UsersController < ApplicationController
before_filter :authorize_admin, except [:index, :show]
def create
# user create code (can't get here if not admin)
end
end
class ApplicationController < ActionController::Base
def authorize_admin
redirect_to root_path, alert: 'Access Denied' unless current_user.admin?
end
end
この単純なアプローチでは、ユーザーが管理者であるかどうかを最初に確認し、管理者でない場合はホームページに追い出すことで、ユーザーレコードに影響を与える可能性のあるコントローラーアクションに対してbeforeフィルターを実行します。
これは単純なアプローチのようです。 deviseコントローラーをサブクラス化する必要があるだけです。その方法については、ドキュメントを参照してください。
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
before_action :authenticate_user!, :redirect_unless_admin, only: [:new, :create]
skip_before_action :require_no_authentication
private
def redirect_unless_admin
unless current_user.try(:admin?)
flash[:error] = "Only admins can do that"
redirect_to root_path
end
end
def sign_up(resource_name, resource)
true
end
end
# config/routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => { :registrations => 'registrations'}
end
説明:
before_action
は、ユーザーがログインしていることを確認し、ユーザーがサインアップしようとすると、管理者でない限りユーザーをリダイレクトします。require_no_authentication
メソッドが原因で発生し、スキップすると問題が解決します。sign_up
ヘルパーメソッドは、自動サインアップを防ぐためにオーバーライドされます。Welcome! You have signed up successfully.
ファイルを編集してconfig/locales/devise.en.yml
サインアップフラッシュメッセージを変更できます。