You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails应用user_path路由报错:id为nil导致路由匹配失败求助

问题:Rails中Posts#index页面个人资料链接触发UrlGenerationError

在Rails应用中添加登录后访问个人资料的按钮链接,路由配置正确,但在Posts#index页面触发ActionController::UrlGenerationError,提示No route matches {:action=>"show", :controller=>"users", :id=>nil, :locale=>:ru},未匹配约束[:id]。手动在浏览器地址栏输入含正确id的链接可正常访问。

相关代码

UsersController代码

class UsersController < ApplicationController
  def index
    @user = User.all
  end
  
  def show
    @user = User.find(params[:id])
    @user_posts = @user.posts
  end
end

布局文件中的链接代码(application.html.erb)

<%= link_to t('.Profile'), user_path(@user), class: "btn btn-outline-#{cookies[:theme] == "dark" ? "light": "dark"} mx-2" %>

路由配置(routes.rb)

Rails.application.routes.draw do
  scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
    root "posts#index"
    devise_for :users
    
    get 'set_theme', to: 'theme#update'
    
    resources :users
    resources :posts, only: [:show, :index]
    resources :tags, only: [:show]
    resources :categories, only: [:show]
    
    namespace :admin do
      resources :users
      resources :categories, except: [:show]
      resources :posts, except: [:show, :index]
    end
  end
end

路由列表(rails routes |grep users输出)

new_user_session GET    (/:locale)/users/sign_in(.:format)
  devise/sessions#new {:locale=>/ru|en/}
                            user_session POST   (/:locale)/users/sign_in(.:format)
  devise/sessions#create {:locale=>/ru|en/}
                    destroy_user_session DELETE (/:locale)/users/sign_out(.:format)
  devise/sessions#destroy {:locale=>/ru|en/}
                       new_user_password GET    (/:locale)/users/password/new(.:format)
  devise/passwords#new {:locale=>/ru|en/}
                      edit_user_password GET    (/:locale)/users/password/edit(.:format)
  devise/passwords#edit {:locale=>/ru|en/}
                           user_password PATCH  (/:locale)/users/password(.:format)
  devise/passwords#update {:locale=>/ru|en/}
                                         PUT    (/:locale)/users/password(.:format)
  devise/passwords#update {:locale=>/ru|en/}
                                         POST   (/:locale)/users/password(.:format)
  devise/passwords#create {:locale=>/ru|en/}
                cancel_user_registration GET    (/:locale)/users/cancel(.:format)
  devise/registrations#cancel {:locale=>/ru|en/}
                   new_user_registration GET    (/:locale)/users/sign_up(.:format)
  devise/registrations#new {:locale=>/ru|en/}
                  edit_user_registration GET    (/:locale)/users/edit(.:format)
  devise/registrations#edit {:locale=>/ru|en/}
                       user_registration PATCH  (/:locale)/users(.:format)
  devise/registrations#update {:locale=>/ru|en/}
                                         PUT    (/:locale)/users(.:format)
  devise/registrations#update {:locale=>/ru|en/}
                                         DELETE (/:locale)/users(.:format)
  devise/registrations#destroy {:locale=>/ru|en/}
                                         POST   (/:locale)/users(.:format)
  devise/registrations#create {:locale=>/ru|en/}
                   new_user_confirmation GET    (/:locale)/users/confirmation/new(.:format)
  devise/confirmations#new {:locale=>/ru|en/}
                       user_confirmation GET    (/:locale)/users/confirmation(.:format)
  devise/confirmations#show {:locale=>/ru|en/}
                                         POST   (/:locale)/users/confirmation(.:format)
  devise/confirmations#create {:locale=>/ru|en/}
                                   users GET    (/:locale)/users(.:format)
  users#index {:locale=>/ru|en/}
                                         POST   (/:locale)/users(.:format)
  users#create {:locale=>/ru|en/}
                                new_user GET    (/:locale)/users/new(.:format)
  users#new {:locale=>/ru|en/}
                               edit_user GET    (/:locale)/users/:id/edit(.:format)
  users#edit {:locale=>/ru|en/}
                                    user GET    (/:locale)/users/:id(.:format)
  users#show {:locale=>/ru|en/}
                                         PATCH  (/:locale)/users/:id(.:format)
  users#update {:locale=>/ru|en/}
                                         PUT    (/:locale)/users/:id(.:format)
  users#update {:locale=>/ru|en/}
                                         DELETE (/:locale)/users/:id(.:format)
  users#destroy {:locale=>/ru|en/}
                             admin_users GET    (/:locale)/admin/users(.:format)
  admin/users#index {:locale=>/ru|en/}
                                         POST   (/:locale)/admin/users(.:format)
  admin/users#create {:locale=>/ru|en/}
                          new_admin_user GET    (/:locale)/admin/users/new(.:format)
  admin/users#new {:locale=>/ru|en/}
                         edit_admin_user GET    (/:locale)/admin/users/:id/edit(.:format)
  admin/users#edit {:locale=>/ru|en/}
                              admin_user GET    (/:locale)/admin/users/:id(.:format)
  admin/users#show {:locale=>/ru|en/}
                                         PATCH  (/:locale)/admin/users/:id(.:format)
  admin/users#update {:locale=>/ru|en/}
                                         PUT    (/:locale)/admin/users/:id(.:format)
  admin/users#update {:locale=>/ru|en/}
                                         DELETE (/:locale)/admin/users/:id(.:format)
  admin/users#destroy {:locale=>/ru|en/}

解决方案

错误核心原因是Posts#index页面中@user变量未赋值(为nil),导致user_path(@user)无法生成包含有效id的路由。

两种修复方式:

  1. 在PostsController中赋值当前用户
    修改posts_controller.rb的index方法,利用Devise提供的current_user获取登录用户:

    class PostsController < ApplicationController
      def index
        # 保留原有帖子列表逻辑
        @posts = Post.all
        # 添加当前用户赋值
        @user = current_user
      end
    end
    
  2. 直接在链接中使用current_user
    无需修改控制器,直接替换链接中的@user为current_user,同时增加登录判断避免未登录时出错:

    <% if user_signed_in? %>
      <%= link_to t('.Profile'), user_path(current_user), class: "btn btn-outline-#{cookies[:theme] == "dark" ? "light": "dark"} mx-2" %>
    <% end %>
    

额外优化建议

UsersController的index方法中变量命名错误,@user = User.all应改为@users = User.all,避免变量名混淆。


内容的提问来源于stack exchange,提问作者NoTProgger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:27:01