如何让管理员通过link_to切换用户的:coach布尔字段状态?
解决Rails中管理员切换用户coach状态的路由及逻辑问题
首先咱们先拆解下你遇到的核心问题:报错No route matches [POST] "/users/1"是因为你用了错误的HTTP方法,加上路由配置和视图逻辑的小问题导致的。我一步步帮你修正:
1. 先修正路由配置
你的routes.rb里有两个明显问题:单数resources :user是拼写错误,而且自定义动作的写法也不对。咱们改成专门的状态切换路由:
# routes.rb resources :users do # 给单个用户添加「切换教练状态」的PATCH路由 patch :toggle_coach, on: :member end get 'signup' => 'users#new' post '/signup' => 'users#create'
这样Rails会生成/users/:id/toggle_coach的路由,专门用来处理单个用户的教练状态切换。
2. 给控制器添加状态切换动作
在users_controller.rb里新增一个专门的动作,只允许管理员访问,直接切换用户的coach字段:
# users_controller.rb # 先确保只有管理员能执行这个动作和删除动作 before_action :admin_user, only: [:toggle_coach, :destroy] def toggle_coach @user = User.find(params[:id]) # 直接反转当前coach状态:true变false,false变true @user.update(coach: !@user.coach) flash[:success] = "教练状态已更新" redirect_to users_path # 切完回到用户列表页 end # 如果你还没定义admin_user方法,记得加上 private def admin_user redirect_to(root_path) unless current_user.admin? end # 另外,给普通用户的编辑/更新动作加权限:普通用户只能改自己,管理员能改所有人 before_action :correct_user, only: [:edit, :update] def correct_user @user = User.find(params[:id]) redirect_to(root_path) unless current_user?(@user) || current_user.admin? end
这样就把状态切换的逻辑封装在专门的动作里,比复用update更清晰。
3. 修正视图里的链接逻辑
你原来的视图写了重复的条件判断,还误用了method: :edit(HTTP里没有这个方法,edit是控制器的GET动作)。咱们简化成动态判断的链接:
# views/users/_user.html.erb <li> <%= link_to image_tag(user.photo.url(:thumb)), user %> <%= link_to user.fname, user %> <%= link_to user.lname, user %> <%= user.email %> <%= user.coach %> <% if current_user.admin? && !current_user?(user) %> | <%= link_to user.coach? ? "Retirer des coachs" : "Passer coach", toggle_coach_user_path(user), method: :patch, data: { confirm: "Êtes vous sûr ?" } %> <% end %> <% if current_user.admin? && !current_user?(user) %> | <%= link_to "Supprimer", user, method: :delete, data: { confirm: "Êtes vous sûr ?" } %> <% end %> </li>
这里用user.coach?动态判断显示的文字,路由用刚才生成的toggle_coach_user_path(user),HTTP方法用:patch(符合Rails更新资源的规范)。
为什么之前的写法不对?
method: :edit是错误的:HTTP方法只有GET/POST/PUT/PATCH/DELETE,edit是控制器用来显示编辑表单的动作,不是HTTP方法。- 路由里的单数
resources :user属于拼写错误,Rails资源路由默认用复数。 - 直接在链接里传
coach: => :true的方式不够安全,也不符合RESTful规范,用专门的toggle动作更清晰可控。
内容的提问来源于stack exchange,提问作者Benjamin Richard
相关产品推荐
相关产品推荐

