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的路由。
两种修复方式:
在PostsController中赋值当前用户
修改posts_controller.rb的index方法,利用Devise提供的current_user获取登录用户:class PostsController < ApplicationController def index # 保留原有帖子列表逻辑 @posts = Post.all # 添加当前用户赋值 @user = current_user end end直接在链接中使用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
相关产品推荐
相关产品推荐

