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

Ruby on Rails devise-roles示例应用权限与文档不符的疑问

Discrepancy Between README and UsersController Logic for Devise Role-Based Access

Hey there, let's break down the clear mismatch you've spotted between the project's README and the actual UsersController code—it's a classic case where the implementation doesn't align with the documented behavior.

What's the Core Conflict?

The README lays out two key expectations:

  • Regular users can view and edit their own personal profiles
  • Regular users cannot modify their own role

But when we look at the controller code, two big issues pop up:

  1. Regular users can't reach the update action at all: The before_action :admin_only, :except => :show locks every action except show to admins. So regular users are blocked from even accessing the update method to edit their profile—this directly contradicts the README's claim.
  2. Admins can only modify roles: The secure_params method only permits the :role attribute. Even if an admin tries to update a user's other profile details (like email, name, etc.), those changes get ignored. This doesn't fit with the idea of "editing personal profiles" for anyone, let alone regular users.

How to Fix This to Match the README

Here are the key adjustments to make the code behave as the documentation describes:

1. Adjust Access Control for the Update Action

Instead of locking all non-show actions to admins, we need to let regular users update their own profiles. Let's tweak the before_action rules and add a custom check:

class UsersController < ApplicationController
  before_action :authenticate_user!
  before_action :admin_or_current_user, only: [:update]
  before_action :admin_only, except: [:show, :update]

  def show
    @user = User.find(params[:id])
    unless current_user.admin? || @user == current_user
      redirect_to root_path, alert: "Access denied."
    end
  end

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(secure_params)
      redirect_to @user, notice: "Profile updated."
    else
      render :edit # Or redirect back with errors
    end
  end

  private

  def admin_only
    unless current_user.admin?
      redirect_to root_path, alert: "Access denied."
    end
  end

  def admin_or_current_user
    @user = User.find(params[:id])
    unless current_user.admin? || current_user == @user
      redirect_to root_path, alert: "Access denied."
    end
  end

  # ... rest of the code ...
end

2. Update secure_params to Allow Proper Profile Edits

We need to split permitted attributes based on user role: regular users can edit their own non-role fields, while admins can manage roles too:

def secure_params
  if current_user.admin?
    # Admins can edit all relevant fields including role
    params.require(:user).permit(:role, :name, :email, :password, :password_confirmation)
  else
    # Regular users can only edit their own profile, not their role
    params.require(:user).permit(:name, :email, :password, :password_confirmation)
  end
end

3. Optional: Add a Dedicated Profile Edit Flow (Cleaner Approach)

For better code organization, you could add a separate edit_profile/update_profile set of actions specifically for regular users to manage their own info, keeping admin-focused user management separate. But the changes above will fix the core mismatch.

Why the Original Code Fails the README's Promise

  • The original before_action rule completely blocks regular users from accessing the update action.
  • The overly restrictive secure_params means even admins can't manage full user profiles—only roles.

With these fixes, regular users will be able to edit their own profile fields (without touching their role), admins can manage all user attributes including roles, and the code will finally match the README's description.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 19:47:49