ruby-on-rails - 使用 Devise 时注册失败如何保持在同一页面上?(注册表格显示在根页面上)
问题描述
我是这个社区的新用户作为登录用户,但在没有登录的情况下已经被你们保存了几次。非常感谢。
我对 Ruby-on-Rails 也比较陌生。
我一直在窃听两天,打算禁用由设计创建的重定向...
基本上,我有一个 home_page ,其中显示了一个自定义注册表单,使用 form_for 并设计如下:
<div class="signup">
<div>
<h2>Create a new account</h2>
<p>It's quick and easy.</p>
</div>
<%= form_for(resource, as: resource, url: registration_path(resource)) do |f| %>
<%#= f.error_notification %>
<div class="form-styling">
<div>
<%= f.text_field :first_name,
required: true,
autofocus: true,
placeholder: "First Name",
label: false,
autocomplete: "off" %>
<%= f.text_field :family_name,
required: true,
placeholder: "Family Name",
label: false,
autocomplete: "off" %>
</div>
<div>
<%= f.text_field :username,
required: true,
placeholder: "Username",
label: false,
autocomplete: "off" %>
<%= f.email_field :email,
required: true,
placeholder: "Email",
label: false,
autocomplete: "off" %>
</div>
<div>
<%= f.password_field :password,
required: true,
hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length),
placeholder: "Password",
label: false,
autocomplete: "new-password" %>
<%= f.password_field :password_confirmation,
required: true,
placeholder: "Password Confirmation",
label: false,
autocomplete: "new-password" %>
</div>
<div>
<%= f.text_field :address,
required: true,
placeholder: "Neighbourhood",
label: false,
autocomplete: "off" %>
</div>
<div class="bottom-signup">
<div class="sign-up-btn">
<%= f.submit "Sign up" %>
</div>
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign up with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %>
<% end %>
<% end %>
</div>
</div>
<% end %>
</div>
此表单可以按需要完美运行,但如果 Devise 所需的参数之一为 false(例如:password_confirmation != password),它会将我重定向到:http://localhost:3000/users
而不是 http://localhost:3000/
我希望显示表单的位置。
这是由于设计框架,我理解,但我似乎无法设法找到解决它的方法..
我试过这样改变设计注册控制器:
class Users::RegistrationsController < Devise::RegistrationsController
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
# GET /resource/sign_up
# def new
# super
# end
# POST /resource
def create
build_resource(sign_up_params)
if resource.save
redirect_to products_path
else
redirect_to root_path
end
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message! :notice, :signed_up
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
set_minimum_password_length
respond_with redirect_to: root_path(resource),
notice: resource.errors['current_password'][0]
end
end
# GET /resource/edit
# def edit
# super
# end
# PUT /resource
# def update
# super
# end
# DELETE /resource
# def destroy
# super
# end
# GET /resource/cancel
# Forces the session data which is usually expired after sign
# in to be expired now. This is useful if the user wants to
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
# def cancel
# super
# end
# protected
# If you have extra params to permit, append them to the sanitizer.
# def configure_sign_up_params
# devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
# end
# If you have extra params to permit, append them to the sanitizer.
# def configure_account_update_params
# devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
# end
# The path used after sign up.
# def after_sign_up_path_for(resource)
# super(resource)
# end
# The path used after sign up for inactive accounts.
# def after_inactive_sign_up_path_for(resource)
# super(resource)
# end
end
这是我的ApplicationController:
class ApplicationController < ActionController::Base
before_action :authenticate_user!
before_action :configure_permitted_parameters, if: :devise_controller?
protect_from_forgery with: :exception
include Pundit
# Pundit: white-list approach.
after_action :verify_authorized, except: :index, unless: :skip_pundit?
after_action :verify_policy_scoped, only: :index, unless: :skip_pundit?
# Uncomment when you *really understand* Pundit!
# rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
# def user_not_authorized
# flash[:alert] = "You are not authorized to perform this action."
# redirect_to(root_path)
# end
private
def skip_pundit?
devise_controller? || params[:controller] =~ /(^(rails_)?admin)|(^pages$)/
end
def configure_permitted_parameters
# For additional fields in app/views/devise/registrations/new.html.erb
devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :family_name, :username, :address])
# For additional in app/views/devise/registrations/edit.html.erb
devise_parameter_sanitizer.permit(:account_update, keys: [:username])
end
def after_sign_in_path_for(resource)
return products_path
end
def after_sign_up_path_for(resource)
return products_path
end
end
这些是我的路线:
devise_scope :user do
get "/sign_in" => "pages#home" # custom path to login/sign_in
get "/sign_up" => "pages#home", as: "new_user_registration" # custom path to sign_up/registration
end
devise_for :users, controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations'
}
root to: 'pages#home'
我对这件事要疯了,但我真的很想了解Devise ..
需要帮助请叫我。
提前致谢!
解决方案
又是我。
经过一番努力,我已经和我的一个朋友解决了这个问题。
这是一条可以禁用自动重定向到设计表单并启用设置您自己的路径并在注册失败后保留在 root_path 上的路径:
1)将这些行添加到您的路线中,以覆盖对设计生成表单的直接回调并自定义您的用户旅程。
devise_for :users, controllers: {
registrations: 'users/registrations'
}
通过这样做,您告诉 Rails 您正在更改用于注册的设计控制器的变量。
2) 在你的 controllers/users/registrations_controller.rb 创建一个新方法 create。
def create
build_resource(sign_up_params)
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message! :notice, :signed_up
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
set_minimum_password_length
render "pages/home"
end
end
我在这里所做的只是将最后一个包裹从:
else
clean_up_passwords resource
set_minimum_password_length
respond_with resource, :location => after_sign_in_path_for(resource)
end
至
else
clean_up_passwords resource
set_minimum_password_length
render "pages/home"
end
3)然后您必须在名为custom_failure.rb的lib 文件夹中创建一个新文件(lib 文件夹中的任何位置都可以正常工作)。在此文件中,添加以下行:
class CustomFailure < Devise::FailureApp
def redirect_url
'/'
end
def route
'/'
end
# You need to override respond to eliminate recall
def respond
if http_auth?
http_auth
else
redirect
end
end
end
在这里,您覆盖响应以消除召回。
4) 然后在config/initializers/devise.rb 中添加以下行:
config.warden do |manager|
manager.failure_app = CustomFailure
end
基本上,在这里您告诉设计查看您刚刚创建的 custom_failure.rb 文件以防发生故障。
5) 最后,在您的config/application.rb中将这些行添加到您的模块中:
config.autoload_paths << Rails.root.join('lib')
在这里,您告诉 Rails 自动加载您的“lib”文件夹和其中的所有文件(这一步似乎对所有用户都不是强制性的,但我的 rails 应用程序还没有自动加载“lib”文件)。
我希望这对你们中的一些人有所帮助。
享受您的代码。
最好的,伊斯特
推荐阅读
- node.js - Nginx - 负载平衡在 Windows 上返回 404
- php - 在php codeigniter中按帖子顺序形成数组帖子
- fonts - 一个词 LaTeX 的全局变化
- angular - Angular 2 模块解析失败:意外的令牌
- selenium - Selenium sendkeys 为反斜杠 (\) 输入管道 (|)
- javascript - 在Angular JS的动态下拉列表中选择默认值
- cdi - Weblogic 从 12.1.2 升级到 12.1.3 时发现 CDIIntegrationService 错误
- r - 用堆叠的条形图ggplot填充矩阵图?
- angular - 从 Angular6 迁移到 Vue
- flowtype - 无法使用 `localStorage.getItem(...)` 调用 `JSON.parse`