我在尝试显示用户个人资料页面时遇到错误“参数丢失或值为空:user_id”
Posted
技术标签:
【中文标题】我在尝试显示用户个人资料页面时遇到错误“参数丢失或值为空:user_id”【英文标题】:I'm running into the error "param is missing or the value is empty: user_id" when trying to display user profile pages 【发布时间】:2021-08-12 07:45:47 【问题描述】:一直在开发我的第一个测试应用,我试图让用户点击下拉菜单中的“我的个人资料”,然后转到他们的个人资料页面。我一直在研究解决方案并空手而归。我知道这是我缺少的一些非常基本的东西,但我无法弄清楚。这是错误的截图
我的导航代码如下:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<div class="browns.helmet.jpeg">
<img src="browns.helmet.jpeg" class="img-fluid">
</div>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" <%= link_to "Home", root_path%>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Image Feed</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Account
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" <%= link_to "My Profile", users_path %>
<li><a class="dropdown-item" <%= link_to "Login", login_path %></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" <%= link_to "Sign Up", new_user_path %>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>
我的路由文件如下:
Rails.application.routes.draw do
get 'photo/index'
get 'photo/store'
resources :users, only: [:new, :create, :show]
get 'login', to: 'sessions#new'
post 'login', to: 'sessions#create'
get 'welcome', to: 'sessions#welcome'
get 'authorized', to: 'sessions#page_requires_login'
get 'users', to: 'users#show'
root 'welcome#index'
end
我的 rake 路线显示如下:
photo_index GET /photo/index(.:format) photo#index
photo_store GET /photo/store(.:format) photo#store
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
user GET /users/:id(.:format) users#show
login GET /login(.:format) sessions#new
POST /login(.:format) sessions#create
welcome GET /welcome(.:format) sessions#welcome
authorized GET /authorized(.:format) sessions#page_requires_login
GET
非常感谢任何帮助。
【问题讨论】:
这种观点本身就有一些问题。在users_path %>
和new_user_path %>
之后缺少</li>
结束标签。 <a class="nav-link active" aria-current="page" <%= link_to "Home", root_path%>
也会导致 html 格式完全错误,因为 link_to
创建了一个锚标记。你想要<%= link_to "Home", root_path, class: 'nav-link active' %>
。我建议使用 HTML 验证器。
【参考方案1】:
您的 UsersController#show
方法应该将用户 ID 视为 params[:id]
,但从错误的外观来看,您正在尝试使用 :user_id
查找它。由于 params 集合中不存在该参数,因此会抛出您看到的错误。如果您将 :user_id
替换为 :id
应该可以。
顺便说一句,在您的路线文件中,您有一行
get 'users', to: 'users#show'
这也是一个潜在的混淆来源,因为它与上面的某些行 resources :users
冲突 - 您正在将应该用于索引操作的路径分配给显示操作,而不包括任何参数。
我会坚持使用 resources
声明,并删除单独的 get
行。
【讨论】:
【参考方案2】:我使用你的路由:config/routes.rb
Rails.application.routes.draw do
get 'photo/index'
get 'photo/store'
resources :users, only: [:new, :create, :show]
get 'login', to: 'sessions#new'
post 'login', to: 'sessions#create'
get 'welcome', to: 'sessions#welcome'
get 'authorized', to: 'sessions#page_requires_login'
get 'users', to: 'users#show'
root 'welcome#index'
end
添加 current_user 和 logged_in?辅助函数:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
helper_method :current_user, :logged_in?
# GET current_user
def current_user
@current_user ||= User.find_by id: session[:user_id]
end
# Check user has logged in before ?
def logged_in?
current_user.present?
end
end
然后稍微修改您的导航以适应上面的帮助器:app/views/layouts/application.html.erb
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<div class="browns.helmet.jpeg">
<img src="browns.helmet.jpeg" class="img-fluid">
</div>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" <%= link_to "Home", root_path%>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Image Feed</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Account
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<% if logged_in? %>
<li><a class="dropdown-item" <%= link_to "My Profile", user_path(current_user) %>
<% else %>
<li><a class="dropdown-item" <%= link_to "Login", login_path %></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" <%= link_to "Sign Up", new_user_path %>
<% end %>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>
注意:<li><a class="dropdown-item" <%= link_to "My Profile", user_path(current_user) %>
,将显示给正确的用户登录。但是您需要允许用户从路由get 'login', to: 'sessions#new'
登录。所以将内容设置为 app/views/sessions/new.html.erb
<div class="container">
<div class="row">
<h1 class="title">Login</h1>
</div>
<div class="row">
<div class="col-lg-offset-3 col-lg-6">
<%= form_for :session, url: login_path do |f| %>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :email, placeholder: "Enter your email", class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, placeholder: "Enter your password",
class: "form-control" %>
</div>
<div class="text-center">
<%= f.submit "Login", class: "btn btn-info col-lg-12" %>
</div>
<div class="text-right">
<%= link_to "Register", new_user_path %>
</div>
<% end %>
</div>
</div>
</div>
此表单会将用户提交给post 'login', to: 'sessions#create'
,因此您需要将其控制为app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
# skip_before_action :authorized, only: [:new, :create, :welcome]
def new
end
def create
user = User.find_by(email: params[:session][:email])
# If you use Devise
# if user && user.authenticate(params[:session][:password])
# If not, use normal check
if user.password == params[:session][:password]
session[:user_id] = user.id
redirect_to '/welcome'
else
Rails.logger.debug 'Can not find user with this email and password!'
end
end
def welcome
end
def login
end
def page_requires_login
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "Logged out!"
end
end
并在 app/views/sessions/welcome.html.erb 为路由 get 'welcome', to: 'sessions#welcome'
编写简单视图
<h1>Welcome</h1>
<%if logged_in?%>
<h1>You are Logged In, <%= current_user.username %></h1>
<%= link_to "Logout", '/logout', method: :get%>
<%else %>
<%= button_to "Login", '/login', method: :get%>
<%= button_to "Sign Up", '/users/new', method: :get%>
<%end%>
现在您可以点击My Profile
,它可以正常工作了。有什么问题告诉我!我会尽力帮助你! : D
【讨论】:
谢谢!到目前为止,我遇到的唯一问题是 Navbar 下拉菜单不再起作用。我试图找出究竟是什么导致它破裂,我遇到了一点砖墙。非常感谢您的详细帮助。以上是关于我在尝试显示用户个人资料页面时遇到错误“参数丢失或值为空:user_id”的主要内容,如果未能解决你的问题,请参考以下文章