私はRails 3アプリでDeviseを使用していますが、この場合、ユーザーは既存のユーザーが作成する必要があります。既存のユーザーは、自分が持つ権限を決定します。
このため、私は欲しい:
これどうやってするの?
現在、devise_for :users
の前に以下を配置することにより、このルートを効果的に削除しています。
match 'users/sign_up' => redirect('/404.html')
それは機能しますが、もっと良い方法があると思いますよね?
Benoit Garretが言ったように、私の場合の最良の解決策は、登録ルートの一括作成をスキップし、実際に必要なものだけを作成することです。
そのために、最初にrake routes
を実行し、次に出力を使用して必要なものを再作成しました。最終結果は次のとおりです。
devise_for :users, :skip => [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users' => 'devise/registrations#update', :as => 'user_registration'
end
ご了承ください:
User
モデルにはまだ:registerable
がありますdevise/registrations
はメールとパスワードの更新を処理しますデフォルトのDeviseパスのルートを削除します。すなわち:
devise_for :users, path_names: {
sign_up: ''
}
私もこれをやろうとしましたが、 devise google groupのスレッド は本当にきれいな解決策を探すことを思いとどまらせました。
JoséValim(Deviseメンテナー)を引用します。
簡単なオプションはありません。パッチを提供するか、:skip =>:registerableを使用して、必要なルートのみを追加できます。
元の質問は:
Railsから特定のルート(削除ルート)を削除する良い方法はありますか?
あなたのモデルでこれを行うことができます
# typical devise setup in User.rb
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
次のように変更します。
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
シンボル:registerable
が削除されたことに注意してください
それだけです、他に何も必要ありません。登録ページへのすべてのルートとリンクも魔法のように削除されます。
devise_invitable パスのcreateおよびnewを削除しようとする同様の問題がありました:
devise_for :users
レーキルート
accept_user_invitation GET /users/invitation/accept(.:format) devise/invitations#edit
user_invitation POST /users/invitation(.:format) devise/invitations#create
new_user_invitation GET /users/invitation/new(.:format) devise/invitations#new
PUT /users/invitation(.:format) devise/invitations#update
devise_for :users , :skip => 'invitation'
devise_scope :user do
get "/users/invitation/accept", :to => "devise/invitations#edit", :as => 'accept_user_invitation'
put "/users/invitation", :to => "devise/invitations#update", :as => nil
end
レーキルート
accept_user_invitation GET /users/invitation/accept(.:format) devise/invitations#edit
PUT /users/invitation(.:format) devise/invitations#update
注1スコープの考案 https://github.com/plataformatec/devise#configuring-routes
注2devise_invitableに適用していますが、任意のdevise * able機能で動作します
重要な注意:devise_scopeがonuserではなくusers?それは正しいです、これに注意してください!この問題を引き起こす多くの痛みを引き起こす可能性があります:
Started GET "/users/invitation/accept?invitation_token=xxxxxxx" for 127.0.0.1
Processing by Devise::InvitationsController#edit as HTML
Parameters: {"invitation_token"=>"6Fy5CgFHtjWfjsCyr3hG"}
[Devise] Could not find devise mapping for path "/users/invitation/accept? invitation_token=6Fy5CgFHtjWfjsCyr3hG".
This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do
match "/some/route" => "some_devise_controller"
end
2) You are testing a Devise controller bypassing the router.
If so, you can explicitly tell Devise which mapping to use:
@request.env["devise.mapping"] = Devise.mappings[:user]
別の投稿 がこれに似ており、@ chrisnicolaが出した回答を共有したいと思いました。投稿では、本番中にユーザーのサインアップのみをブロックしようとしていました。
登録コントローラーを変更することもできます。次のようなものを使用できます。
In "app/controllers/registrations_controller.rb"
class RegistrationsController < Devise::RegistrationsController
def new
flash[:info] = 'Registrations are not open.'
redirect_to root_path
end
def create
flash[:info] = 'Registrations are not open.'
redirect_to root_path
end
end
これにより、deviseのコントローラーがオーバーライドされ、代わりに上記のメソッドが使用されます。誰かが何らかの理由でsign_upページにたどり着いた場合に備えて、フラッシュメッセージを追加しました。また、任意のパスへのリダイレクトを変更できる必要があります。
また "config/routes.rb"でこれを追加できます:
devise_for :users, :controllers => { :registrations => "registrations" }
このようにすると、標準のデバイスを使用してプロファイルを編集できます。必要に応じて、プロファイル編集オプションを上書きすることもできます。
def update
end
"app/controllers/registrations_controller.rb"
「devise_for」の前に配置することで、「devise_scope」をオーバーライドできます。
devise_scope :user do
get "/users/sign_up", :to => "sites#index"
end
devise_for :users
これが最善の方法であるかどうかはわかりませんが、サインインページにリダイレクトするだけなので、現在の私のソリューションです。
これは古い質問ですが、最近同じ問題を解決し、次の方法よりもはるかにエレガントなソリューションを思い付きました。
devise_for :users, :skip => [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users' => 'devise/registrations#update', :as => 'user_registration'
end
そして、過度に冗長になることなく、名前付きルートのデフォルト名(cancel_user_registration
など)を提供します。
devise_for :users, skip: [:registrations]
# Recreates the Devise registrations routes
# They act on a singular user (the signed in user)
# Add the actions you want in 'only:'
resource :users,
only: [:edit, :update, :destroy],
controller: 'devise/registrations',
as: :user_registration do
get 'cancel'
end
rake routes
デフォルトのdeviseモジュールでの出力:
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
Routes.rbでこれを行う
devise_for :users, :controllers => {:registrations => "registrations"}, :skip => [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users' => 'devise/registrations#update', :as => 'user_registration'
end
devise_scope :user do
get "/sign_in", :to => "devise/sessions#new"
get "/sign_up", :to => "devise/registrations#new"
end
サインインページにアクセスしてエラーを修正すると、エラーが発生します。この変更は、app/views/devise/shared/_links.erbで行います。
<% if request.path != "/sign_in" %>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
<% end %>
@maxの answer が気に入りましたが、使用しようとするとdevise_mapping
がnilであるためエラーになりました。
私は彼の解決策を問題に対処しているように少し修正しました。 devise_scope
内のresource
への呼び出しをラップする必要がありました。
devise_for :users, skip: [:registrations]
devise_scope :user do
resource :users,
only: [:edit, :update, :destroy],
controller: 'devise/registrations',
as: :user_registration do
get 'cancel'
end
end
devise_scope
には単数の:user
が必要ですが、resource
には複数の:users
が必要です。
これは、ルートをいじったり、アプリケーションコントローラーメソッドを追加したりしなくてもうまく機能することがわかりました。私のアプローチは、deviseメソッドをオーバーライドすることです。これをapp/controllers/devise/registrations_controller.rb
に追加します。簡潔にするため、他の方法は省略しました。
class Devise::RegistrationsController < DeviseController
...
# GET /resource/sign_up
def new
redirect_to root_path
end
....
end
また、このパスが他のビューからまだ到達可能であるという幻想を取り除くために、app/views/devise/shared/_links.erb
からこのコードを削除することもできます。
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
私の場合、他の人のために。
with devise (3.5.2)
。
サインアップへのルートを正常に削除しましたが、次のコードを使用して、プロファイルを編集するためのルートを保持しました。
#routes.rb
devise_for :users, skip: [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put '/users(.:format)' => 'devise/registrations#update', as: 'user_registration'
patch '/users(.:format)' => 'devise/registrations#update'
end
ここに私が行ったわずかに異なるルートがあります。これにより、devise/shared/_links.html.erb
ビューをオーバーライドする必要がなくなります。
app/models/user.rb
::
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
config/routes.rb
::
devise_for :users
devise_scope :user do
put 'users' => 'devise/registrations#update', as: 'user_registration'
get 'users/edit' => 'devise/registrations#edit', as: 'edit_user_registration'
delete 'users' => 'devise/registrations#destroy', as: 'registration'
end
$ rake routes | grep devise
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
$ rake routes | grep devise
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
user_registration PUT /users(.:format) devise/registrations#update
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
registration DELETE /users(.:format) devise/registrations#destroy
ルートを変更すると、それに伴う他の問題が山ほどあります。私が見つけた最も簡単な方法は、以下を実行することです。
ApplicationController < ActionController::Base
before_action :dont_allow_user_self_registration
private
def dont_allow_user_self_registration
if ['devise/registrations','devise_invitable/registrations'].include?(params[:controller]) && ['new','create'].include?(params[:action])
redirect_to root_path
end
end
end
私は同じ問題を抱えていたので、登録ページからユーザーをリダイレクトすることは少し悪い習慣であることがわかりました。したがって、私の解決策は基本的に:registrable
をまったく使用しないことです。
私がやったのは、ユーザーの詳細を編集するような似たようなページを作成することでした:
<%= form_tag(update_user_update_path, method: :post) do %>
<br>
<%= label_tag(:currPassword, 'Current password:') %> <%= password_field_tag(:currPassword) %> <br>
<%= label_tag(:newPassword, 'New password:') %> <%= password_field_tag(:newPassword) %> <br>
<%= label_tag(:newPasswordConfirm, 'Confirm new password:') %> <%= password_field_tag(:newPasswordConfirm) %> <br>
<%= submit_tag('Update') %>
<% end %>
したがって、このフォームは、次のようなパスワードを更新する新しいポストエンドポイントに送信します。
def update
currPass = params['currPassword']
newPass1 = params['newPassword']
newPass2 = params['newPasswordConfirm']
currentUserParams = Hash.new()
currentUserParams[:current_password] = currPass
currentUserParams[:password] = newPass1
currentUserParams[:password_confirmation] = newPass2
@result = current_user.update_with_password(currentUserParams)
end
後で、ビューで@result
を使用して、パスワードが更新されたかどうかをユーザーに伝えることができます。