Ruby on rails Rails 4将登录设计为一个弹出窗口
Hi Iam使用Desive对用户进行身份验证 我已经按照各种教程获得了一个弹出窗口登录,但我没有成功,请任何人告诉详细如何做到这一点。我尝试了各种教程,但没有任何效果,每件事都是重新重定向到登录页面 我是rails的新手,请帮忙 我无法在同一页上登录 这是我新的.html.erbRuby on rails Rails 4将登录设计为一个弹出窗口,ruby-on-rails,devise,ruby-on-rails-4,Ruby On Rails,Devise,Ruby On Rails 4,Hi Iam使用Desive对用户进行身份验证 我已经按照各种教程获得了一个弹出窗口登录,但我没有成功,请任何人告诉详细如何做到这一点。我尝试了各种教程,但没有任何效果,每件事都是重新重定向到登录页面 我是rails的新手,请帮忙 我无法在同一页上登录 这是我新的.html.erb <%= form_for(:user, :html => {:id => 'login_form'}, :url => user_session_path, :remote => :t
<%= form_for(:user, :html => {:id => 'login_form'}, :url => user_session_path, :remote => :true, :format => :json) do |f| %>
<%= f.email_field :email, :autofocus => true, :placeholder => "email", :id => 'login_email' %>
<%= f.password_field :password, :placeholder => "password", :id => 'login_password' %>
<% if devise_mapping.rememberable? -%>
<div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
<% end -%>
<div><%= image_submit_tag('modals/account/login_submit.png') %></div>
<% end %>
{:id=>'login_form'},:url=>user_session_path,:remote=>:true,:format=>:json)do | f |%>
true,:占位符=>“电子邮件”,:id=>“登录\电子邮件”%>
“密码”,:id=>“登录\密码”%>
这是我的标题页
<% if user_signed_in? %>
<p>Welcome <%= current_user.email %></p>
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
<% else %>
<p>You are not signed in.</p>
<%= link_to "Sign in", new_user_session_path, :remote => :true %>
<% end %>
欢迎光临
:删除%>
您尚未登录
:真%>
首先,你想要一张支票吗
弹出窗口是新窗口,让人想起90年代的广告,而弹出窗口(有时称为modals)是UI中的集成元素,基本上只是深色背景上的一个div
所有Web2.0网站都使用弹出窗口来增强可用性,而弹出窗口则有损于体验:)
弹出窗口
#config/routes.rb
devise_for :users, :path => '', :controllers => {:sessions => 'sessions', :registrations => 'registrations'}, :path_names => { :sign_in => 'login', :password => 'forgot', :confirmation => 'confirm', :unlock => 'unblock', :registration => 'register', :sign_up => 'new', :sign_out => 'logout'}
我们已经实现了您寻求的功能
要使这项工作顺利进行,您必须做好几件事——我将在这里为您详细介绍:
路线
#config/routes.rb
devise_for :users, :path => '', :controllers => {:sessions => 'sessions', :registrations => 'registrations'}, :path_names => { :sign_in => 'login', :password => 'forgot', :confirmation => 'confirm', :unlock => 'unblock', :registration => 'register', :sign_up => 'new', :sign_out => 'logout'}
第一步是对路线进行排序
尽管Deviate有,但您需要自定义路由,以包括自定义的会话
/注册
控制器,以及您想要的任何自定义路径
路由最重要的部分是(您需要自定义控制器!):
控制器
#config/routes.rb
devise_for :users, :path => '', :controllers => {:sessions => 'sessions', :registrations => 'registrations'}, :path_names => { :sign_in => 'login', :password => 'forgot', :confirmation => 'confirm', :unlock => 'unblock', :registration => 'register', :sign_up => 'new', :sign_out => 'logout'}
接下来,您需要向会话
和注册
控制器添加ajax响应功能。即使Desive在每次安装时都会添加这些控制器,但它们仍然是隐藏的,如果您想添加功能,就必须对其进行扩展
以下是我们的会话和注册控制器(此代码中的许多代码可以删除,但它现在适用于我们):
会话
#app/controllers/sessions_controller.rb
class SessionsController < DeviseController
prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
prepend_before_filter :allow_params_authentication!, :only => :create
prepend_before_filter { request.env["devise.skip_timeout"] = true }
prepend_view_path 'app/views/devise'
# GET /resource/sign_in
def new
self.resource = resource_class.new(sign_in_params)
clean_up_passwords(resource)
respond_with(resource, serialize_options(resource))
end
# POST /resource/sign_in
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_to do |format|
format.json { render :json => {}, :status => :ok }
format.html { respond_with resource, :location => after_sign_in_path_for(resource) }
end
end
# DELETE /resource/sign_out
def destroy
redirect_path = after_sign_out_path_for(resource_name)
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
set_flash_message :notice, :signed_out if signed_out && is_navigational_format?
# We actually need to hardcode this as Rails default responder doesn't
# support returning empty response on GET request
respond_to do |format|
format.all { head :no_content }
format.any(*navigational_formats) { redirect_to redirect_path }
end
end
protected
def sign_in_params
devise_parameter_sanitizer.sanitize(:sign_in)
end
def serialize_options(resource)
methods = resource_class.authentication_keys.dup
methods = methods.keys if methods.is_a?(Hash)
methods << :password if resource.respond_to?(:password)
{ :methods => methods, :only => [:password] }
end
def auth_options
{ :scope => resource_name, :recall => "#{controller_path}#new" }
end
end
#app/controllers/registrations_controller.rb
class RegistrationsController < DeviseController
prepend_before_filter :require_no_authentication, :only => [ :new, :create, :cancel ]
prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]
before_filter :configure_permitted_parameters
prepend_view_path 'app/views/devise'
# GET /resource/sign_up
def new
build_resource({})
respond_with self.resource
end
# POST /resource
def create
build_resource(sign_up_params)
if resource.save
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
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}" if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
respond_to do |format|
format.json { render :json => resource.errors, :status => :unprocessable_entity }
format.html { respond_with resource }
end
end
end
# GET /resource/edit
def edit
render :edit
end
# PUT /resource
# We need to use a copy of the resource because we don't want to change
# the current user in place.
def update
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
if update_resource(resource, account_update_params)
if is_navigational_format?
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
:update_needs_confirmation : :updated
set_flash_message :notice, flash_key
end
sign_in resource_name, resource, :bypass => true
respond_with resource, :location => after_update_path_for(resource)
else
clean_up_passwords resource
respond_with resource
end
end
# DELETE /resource
def destroy
resource.destroy
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
set_flash_message :notice, :destroyed if is_navigational_format?
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
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
expire_session_data_after_sign_in!
redirect_to new_registration_path(resource_name)
end
protected
# Custom Fields
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:first_name, :last_name,
:email, :password, :password_confirmation)
end
end
def update_needs_confirmation?(resource, previous)
resource.respond_to?(:pending_reconfirmation?) &&
resource.pending_reconfirmation? &&
previous != resource.unconfirmed_email
end
# By default we want to require a password checks on update.
# You can overwrite this method in your own RegistrationsController.
def update_resource(resource, params)
resource.update_with_password(params)
end
# Build a devise resource passing in the session. Useful to move
# temporary session data to the newly created user.
def build_resource(hash=nil)
self.resource = resource_class.new_with_session(hash || {}, session)
end
# Signs in a user on sign up. You can overwrite this method in your own
# RegistrationsController.
def sign_up(resource_name, resource)
sign_in(resource_name, resource)
end
# The path used after sign up. You need to overwrite this method
# in your own RegistrationsController.
def after_sign_up_path_for(resource)
after_sign_in_path_for(resource)
end
# The path used after sign up for inactive accounts. You need to overwrite
# this method in your own RegistrationsController.
def after_inactive_sign_up_path_for(resource)
respond_to?(:root_path) ? root_path : "/"
end
# The default url to be used after updating a resource. You need to overwrite
# this method in your own RegistrationsController.
def after_update_path_for(resource)
signed_in_root_path(resource)
end
# Authenticates the current scope and gets the current resource from the session.
def authenticate_scope!
send(:"authenticate_#{resource_name}!", :force => true)
self.resource = send(:"current_#{resource_name}")
end
def sign_up_params
devise_parameter_sanitizer.sanitize(:sign_up)
end
def account_update_params
devise_parameter_sanitizer.sanitize(:account_update)
end
end
#app/views/devise/sessions/new.html.erb
<%= form_for(devise_resource, :as => devise_resource_name, :html => {:id => 'login_form'}, :url => user_session_path, :remote => :true, :format => :json) do |f| %>
<%= f.email_field :email, :autofocus => true, :placeholder => "email", :id => 'login_email' %>
<%= f.password_field :password, :placeholder => "password", :id => 'login_password' %>
<% if devise_mapping.rememberable? -%>
<div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
<% end -%>
<div><%= image_submit_tag('modals/account/login_submit.png') %></div>
<% end %>
//app/assets/javscripts/application.js
$(document).on('submit', '#login_form', function(e) {
//do stuff here
}).on('ajax:success', '#login_form', function(e, data, status, xhr) {
//do stuff here
}).on('ajax:error', '#login_form', function(e, data, status, xhr) {
//do stuff here
});
注册
#app/views/devise/registrations/new.html.erb
<%= form_for(devise_resource, :as => devise_resource_name, :html => {:id => 'register_form'}, :url => user_registration_path, :remote => :true, :format => :json) do |f| %>
<div class="name_input_container">
<div class="name_input_cell">
<%= f.text_field :first_name, :autofocus => true, :class => 'first_name', :placeholder => 'first name' %>
<div class="error"><%= devise_resource.errors[:first_name].first if devise_resource.errors[:first_name].present? %></div>
</div>
<div class="name_input_cell_right">
<%= f.text_field :last_name, :class => 'last_name', :placeholder => 'last name' %>
<div class="error"><%= devise_resource.errors[:last_name].first if devise_resource.errors[:last_name].present? %></div>
</div>
</div>
<%= f.email_field :email, :placeholder => "email" %>
<div class="error"><%= devise_resource.errors[:email].first if devise_resource.errors[:email].present? %></div>
<%= f.password_field :password, :placeholder => "password", :title => "8+ characters" %>
<div class="error"><%= devise_resource.errors[:password].first if devise_resource.errors[:password].present? %></div>
<%= f.password_field :password_confirmation, :placeholder => "confirm password" %>
<div class="error"><%= devise_resource.errors[:password_confirmation].first if devise_resource.errors[:password_confirmation].present? %></div>
<div class="option_buttons">
<div class="already_registered">
<%= link_to 'already registered?', '#', :class => 'already_registered', :id => 'already_registered', :view => 'login' %>
</div>
<%= image_submit_tag('modals/account/register_submit.png', :class => 'go') %>
<div class="clear"></div>
</div>
<% end %>
//app/assets/javascripts/application.js
$(document).on('submit', '#register_form', function(e){
//do stuff here
}).on('ajax:success', '#register_form', function(e, data, status, xhr) {
//do stuff here
}).on('ajax:error', '#register_form', function(e, data, status, xhr) {
//do stuff here
});
你看了吗?是的,我试过了,不起作用。好吧,那么你需要展示你有什么,为什么不起作用。否则,看起来你是在试图让别人帮你做你的工作。我只是按照博客中的步骤做了,它不起作用,它只是进入新的登录页面。好吧,老实说,你要么需要发布到目前为止你所拥有的(最好是一个,或者只是在您的端进行一些繁重的调试。在不查看您的实现外观的情况下进行诊断是不可能的,任何人在这里发布的任何解决方案都只会重复已经存在的许多博客和教程。您说过,提交后,您将被重定向到登录页面,而不是r比成功登录的地方要多。那么,是什么原因造成的呢?要么是代码中的错误,要么是身份验证失败。你有自己的出发点。Hi Rich peck非常感谢你的教程。在执行你的教程时,我遇到了上面的错误。你能告诉我如何解决它吗?Hi Rich peck我已经解决了这个问题。但我不能o在同一页面中打开。它再次重定向到新页面。它重定向到哪个页面?我使用了引导模式,并在模式正文中粘贴了注册表单和登录表单,它成功了。我需要添加什么到登录和注册,以使其在没有引导模式的情况下工作?谢谢你,Discus仍然使用弹出窗口进行注册在里面