我在尝试显示用户个人资料页面时遇到错误“参数丢失或值为空: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 %&gt;new_user_path %&gt; 之后缺少&lt;/li&gt; 结束标签。 &lt;a class="nav-link active" aria-current="page" &lt;%= link_to "Home", root_path%&gt; 也会导致 html 格式完全错误,因为 link_to 创建了一个锚标记。你想要&lt;%= link_to "Home", root_path, class: 'nav-link active' %&gt;。我建议使用 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> 

注意:&lt;li&gt;&lt;a class="dropdown-item" &lt;%= link_to "My Profile", user_path(current_user) %&gt;,将显示给正确的用户登录。但是您需要允许用户从路由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”的主要内容,如果未能解决你的问题,请参考以下文章

如何从 laravel 中的某个路由页面检索图像或文件?

你好。我在更改 django 项目中显示找不到页面的页面时遇到问题(404)

为啥我在尝试执行时间戳用户定义函数时遇到运行时错误(范围)

表单提交后,WebView 未加载页面

在 user_name 的占位符中获取错误值

我在尝试实现hateoas时遇到编译时错误,它没有向我显示方法On方法