两个 类 用户在尝试显示个人资料页面时发生冲突
Two classes of users conflicting when trying to show profile pages
我创建了两种类型的用户 - "users" 和 "shops"。我的应用程序设置为当用户登录时,他们会被发送到主页,然后通过 ruby if-elsif-else 逻辑显示他们的个人资料。
我的问题是逻辑的第二部分 elsif 无法正常工作,它正在呈现主页而不是商店资料页面。
home.html.erb
<% if logged_in? %> // corresponds to "user" model
<div>
<aside class="col-md-4">
<div>
<h1>My Profile</h1>
</div>
<div class="hero-unit user_info">
<%= render 'shared/user_info' %>
</div>
<section class="hero-unit car_form">
<%= render 'shared/car_form' %>
</section>
</aside>
<div class="col-md-8">
<h1>My Cars</h1>
</div>
<div class="col-md-8">
<%= render 'shared/feed' %>
</div>
</div>
<% elsif shop_logged_in? %> // checks if a shop has logged in
<div class="col-md-8">
<%= render 'shared/shop_info' %>
</div>
<% else %> //If no one is logged in, home page is shown
<div class="broke col-md-12">
<div class="alive">
<h1>Keep your car on the road<%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %></h1>
</div>
</div>
我需要 <% elsif shop_logged_in? %>
部分才能正常工作。这是在 ShopSessionHelper 中定义的:
def shop_logged_in?
!current_shop.nil?
end
然后是 user/driver class 的 SessionHelper。我有点担心两者之间的一些重叠,但它似乎工作正常(欢迎在这里提出建议)。
def logged_in?
!current_user.nil?
end
这两个应该判断登录的是用户还是商店,并使用上述逻辑呈现正确的页面。为什么它不起作用?
为了完整起见,这里是我的控制器和助手的完整信息:
sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
redirect_to root_path
else
#Show error message
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
log_out if logged_in?
redirect_to root_url
end
end
sessions_helper.rb
module SessionsHelper
# Logs in the given user.
def log_in(user)
session[:user_id] = user.id
end
# Remembers a user in a persistent session.
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
def current_user?(user)
user == current_user
end
# Returns the user corresponding to the remember token cookie.
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
# Returns true if the user is logged in, false otherwise.
def logged_in?
!current_user.nil?
end
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
# Logs out the current user.
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
# Redirects to stored location (or to the default).
def redirect_back_or(default)
redirect_to(root_url)
session.delete(:forwarding_url)
end
# Stores the URL trying to be accessed.
def store_location
session[:forwarding_url] = request.url if request.get?
end
end
shop_sessions_controller.rb
class ShopSessionsController < ApplicationController
def new
end
def create
shop = Shop.find_by(email: params[:session][:email].downcase)
if shop && shop.authenticate(params[:session][:password])
log_in shop
params[:session][:remember_me] == '1' ? remember(shop) : forget(shop)
redirect_to root_path
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
shop_sessions_helper.rb
module ShopSessionsHelper
# Logs in the given shop.
def log_in(shop)
session[:shop_id] = shop.id
end
# Remembers a shop in a persistent session.
def remember(shop)
shop.remember
cookies.permanent.signed[:shop_id] = shop.id
cookies.permanent[:remember_token] = shop.remember_token
end
def current_shop?(shop)
shop == current_shop
end
# Returns the shop corresponding to the remember token cookie.
def current_shop
if (shop_id = session[:shop_id])
@current_shop ||= Shop.find_by(id: shop_id)
elsif (shop_id = cookies.signed[:shop_id])
shop = Shop.find_by(id: shop_id)
if shop && shop.authenticated?(cookies[:remember_token])
log_in shop
@current_shop = shop
end
end
end
# Returns true if the shop is logged in, false otherwise.
def shop_logged_in?
!current_shop.nil?
end
def forget(shop)
shop.forget
cookies.delete(:shop_id)
cookies.delete(:remember_token)
end
# Logs out the current shop.
def log_out
forget(current_shop)
session.delete(:shop_id)
@current_shop = nil
end
# Redirects to stored location (or to the default).
def redirect_back_or(default)
redirect_to(root_url)
session.delete(:forwarding_url)
end
# Stores the URL trying to be accessed.
def store_location
session[:forwarding_url] = request.url if request.get?
end
end
1st 一些建设性的批评。真的需要一个用户会话控制器和一个商店会话控制器吗?我能想到答案是肯定的唯一原因是,如果您的应用程序允许在同一会话中同时登录用户和登录商店。而且我认为这不会发生,因为您的主页逻辑:
<% if logged_in? %> // corresponds to "user" model
<% elsif shop_logged_in? %> // corresponds to "user" model
只检查其中之一,无法处理同时发生的两者。因此,为了简单起见,我将取消 Shop Session Controller,并在单个 Sessions Controller 中同时处理 Shop Session 和 User Sessions。
根据您在下面的评论,当用户登录时,为了处理不允许商店登录的问题,我会这样做:
在 Shop Sessions Helper 中将 def log_out
修改为 def shop_log_out
,并在 User Sessions Helper 中将其添加到 log_in
:
商店会话助手:
def shop_log_out
#your same code from before
end
用户会话助手:
def log_in(user)
session[:user_id] = user.id
if shop_logged_in? #check if a shop is logged in
shop_log_out #and log shop out if true
end
end
现在,如果有商店登录,则每当用户登录时,它将被注销,防止两者同时发生。
如果您选择忽略我关于只使用一个会话控制器的建议,我会这样做:
<% elsif shop_logged_in? %> // checks if a shop has logged in
失败了。尝试使用 puts
追溯您的方法,找出失败的地方。我一次只退回一种方法,从:
开始
def shop_logged_in?
puts "-------------------------" #add this code
puts "current_shop = #{current_shop}" #this code
puts "-------------------------" #and this code
!current_shop.nil?
end
然后保存代码并导航到您的主页。
您很可能会收到一条错误消息,指出 current_shop 为 nil。
现在从 shop_logged_in?
中删除那些 puts
并转到 def current_shop
:
def current_shop
if (shop_id = session[:shop_id])
puts "---------------------" #add this
puts "inside current_shop if" #and this
@current_shop ||= Shop.find_by(id: shop_id)
elsif (shop_id = cookies.signed[:shop_id])
shop = Shop.find_by(id: shop_id)
if shop && shop.authenticated?(cookies[:remember_token])
log_in shop
@current_shop = shop
end
end
end
如果上面修改后的代码在终端中没有任何内容,那么我会将 puts
向下移动到 elsif
中以找出您正在流经的逻辑部分。如果这些 puts
都不是,那么您就知道 if
和 def current_shop
内部的 elsif
都不为真。
如果是这样,那么我会说您的 routes.rb
文件有误。您的商店登录路径是否指向 shopsession#new
?
我能想到的另一件事是您忘记在应用程序控制器中添加 include ShopSessionsHelper
。
我创建了两种类型的用户 - "users" 和 "shops"。我的应用程序设置为当用户登录时,他们会被发送到主页,然后通过 ruby if-elsif-else 逻辑显示他们的个人资料。
我的问题是逻辑的第二部分 elsif 无法正常工作,它正在呈现主页而不是商店资料页面。
home.html.erb
<% if logged_in? %> // corresponds to "user" model
<div>
<aside class="col-md-4">
<div>
<h1>My Profile</h1>
</div>
<div class="hero-unit user_info">
<%= render 'shared/user_info' %>
</div>
<section class="hero-unit car_form">
<%= render 'shared/car_form' %>
</section>
</aside>
<div class="col-md-8">
<h1>My Cars</h1>
</div>
<div class="col-md-8">
<%= render 'shared/feed' %>
</div>
</div>
<% elsif shop_logged_in? %> // checks if a shop has logged in
<div class="col-md-8">
<%= render 'shared/shop_info' %>
</div>
<% else %> //If no one is logged in, home page is shown
<div class="broke col-md-12">
<div class="alive">
<h1>Keep your car on the road<%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %></h1>
</div>
</div>
我需要 <% elsif shop_logged_in? %>
部分才能正常工作。这是在 ShopSessionHelper 中定义的:
def shop_logged_in?
!current_shop.nil?
end
然后是 user/driver class 的 SessionHelper。我有点担心两者之间的一些重叠,但它似乎工作正常(欢迎在这里提出建议)。
def logged_in?
!current_user.nil?
end
这两个应该判断登录的是用户还是商店,并使用上述逻辑呈现正确的页面。为什么它不起作用?
为了完整起见,这里是我的控制器和助手的完整信息:
sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
redirect_to root_path
else
#Show error message
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
log_out if logged_in?
redirect_to root_url
end
end
sessions_helper.rb
module SessionsHelper
# Logs in the given user.
def log_in(user)
session[:user_id] = user.id
end
# Remembers a user in a persistent session.
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
def current_user?(user)
user == current_user
end
# Returns the user corresponding to the remember token cookie.
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
# Returns true if the user is logged in, false otherwise.
def logged_in?
!current_user.nil?
end
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
# Logs out the current user.
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
# Redirects to stored location (or to the default).
def redirect_back_or(default)
redirect_to(root_url)
session.delete(:forwarding_url)
end
# Stores the URL trying to be accessed.
def store_location
session[:forwarding_url] = request.url if request.get?
end
end
shop_sessions_controller.rb
class ShopSessionsController < ApplicationController
def new
end
def create
shop = Shop.find_by(email: params[:session][:email].downcase)
if shop && shop.authenticate(params[:session][:password])
log_in shop
params[:session][:remember_me] == '1' ? remember(shop) : forget(shop)
redirect_to root_path
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
shop_sessions_helper.rb
module ShopSessionsHelper
# Logs in the given shop.
def log_in(shop)
session[:shop_id] = shop.id
end
# Remembers a shop in a persistent session.
def remember(shop)
shop.remember
cookies.permanent.signed[:shop_id] = shop.id
cookies.permanent[:remember_token] = shop.remember_token
end
def current_shop?(shop)
shop == current_shop
end
# Returns the shop corresponding to the remember token cookie.
def current_shop
if (shop_id = session[:shop_id])
@current_shop ||= Shop.find_by(id: shop_id)
elsif (shop_id = cookies.signed[:shop_id])
shop = Shop.find_by(id: shop_id)
if shop && shop.authenticated?(cookies[:remember_token])
log_in shop
@current_shop = shop
end
end
end
# Returns true if the shop is logged in, false otherwise.
def shop_logged_in?
!current_shop.nil?
end
def forget(shop)
shop.forget
cookies.delete(:shop_id)
cookies.delete(:remember_token)
end
# Logs out the current shop.
def log_out
forget(current_shop)
session.delete(:shop_id)
@current_shop = nil
end
# Redirects to stored location (or to the default).
def redirect_back_or(default)
redirect_to(root_url)
session.delete(:forwarding_url)
end
# Stores the URL trying to be accessed.
def store_location
session[:forwarding_url] = request.url if request.get?
end
end
1st 一些建设性的批评。真的需要一个用户会话控制器和一个商店会话控制器吗?我能想到答案是肯定的唯一原因是,如果您的应用程序允许在同一会话中同时登录用户和登录商店。而且我认为这不会发生,因为您的主页逻辑:
<% if logged_in? %> // corresponds to "user" model
<% elsif shop_logged_in? %> // corresponds to "user" model
只检查其中之一,无法处理同时发生的两者。因此,为了简单起见,我将取消 Shop Session Controller,并在单个 Sessions Controller 中同时处理 Shop Session 和 User Sessions。
根据您在下面的评论,当用户登录时,为了处理不允许商店登录的问题,我会这样做:
在 Shop Sessions Helper 中将 def log_out
修改为 def shop_log_out
,并在 User Sessions Helper 中将其添加到 log_in
:
商店会话助手:
def shop_log_out
#your same code from before
end
用户会话助手:
def log_in(user)
session[:user_id] = user.id
if shop_logged_in? #check if a shop is logged in
shop_log_out #and log shop out if true
end
end
现在,如果有商店登录,则每当用户登录时,它将被注销,防止两者同时发生。
如果您选择忽略我关于只使用一个会话控制器的建议,我会这样做:
<% elsif shop_logged_in? %> // checks if a shop has logged in
失败了。尝试使用 puts
追溯您的方法,找出失败的地方。我一次只退回一种方法,从:
def shop_logged_in?
puts "-------------------------" #add this code
puts "current_shop = #{current_shop}" #this code
puts "-------------------------" #and this code
!current_shop.nil?
end
然后保存代码并导航到您的主页。 您很可能会收到一条错误消息,指出 current_shop 为 nil。
现在从 shop_logged_in?
中删除那些 puts
并转到 def current_shop
:
def current_shop
if (shop_id = session[:shop_id])
puts "---------------------" #add this
puts "inside current_shop if" #and this
@current_shop ||= Shop.find_by(id: shop_id)
elsif (shop_id = cookies.signed[:shop_id])
shop = Shop.find_by(id: shop_id)
if shop && shop.authenticated?(cookies[:remember_token])
log_in shop
@current_shop = shop
end
end
end
如果上面修改后的代码在终端中没有任何内容,那么我会将 puts
向下移动到 elsif
中以找出您正在流经的逻辑部分。如果这些 puts
都不是,那么您就知道 if
和 def current_shop
内部的 elsif
都不为真。
如果是这样,那么我会说您的 routes.rb
文件有误。您的商店登录路径是否指向 shopsession#new
?
我能想到的另一件事是您忘记在应用程序控制器中添加 include ShopSessionsHelper
。