【问题标题】:I'm running into the error "param is missing or the value is empty: user_id" when trying to display user profile pages我在尝试显示用户个人资料页面时遇到错误“参数丢失或值为空:user_id”
【发布时间】: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 验证器。

标签: ruby-on-rails ruby bootstrap-4


【解决方案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 下拉菜单不再起作用。我试图找出究竟是什么导致它破裂,我遇到了一点砖墙。非常感谢您的详细帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    • 2022-12-02
    • 2016-01-07
    • 1970-01-01
    相关资源
    最近更新 更多