【问题标题】:Edit User Information as Admin以管理员身份编辑用户信息
【发布时间】:2015-07-18 15:40:10
【问题描述】:

我正在通过 Rails 4+ 开发一个项目,我希望管理员能够编辑用户信息。目前,我在我的用户模型中将 admin 作为布尔值(使用 Devise 时)。管理员帐户目前可以从站点中删除用户,但在编辑用户信息时我似乎感到困惑。

我一直在网上阅读,我不想使用 cancan 或其他 gem,因为我认为它真的不需要?此外,我还没有真正设置任何代码,因为我对如何实现这一点感到非常困惑。不是在寻找一个简单/快速的答案,我只是迷失了,我不知道从哪里/如何开始。

如果您知道如何完成此操作和/或任何可以提供帮助的指南,我将不胜感激。

谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 authentication devise


    【解决方案1】:

    这实际上并不难实现。我没有使用 CanCan,也没有在我将要向您展示的代码中使用 Devise,它都是手动制作的。但是,我仍然认为它可能会对您有所帮助...

    考虑一个示例 users_controller.rb 文件...

    class UsersController < ApplicationController
      before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
      before_action :correct_user,   only: [:edit, :update]
      .
      .
      def edit
        @user = User.find(params[:id])
      end
      .
      .
      private
        .
        .
        # Confirms that user is correct.
        def correct_user
          @user = User.find(params[:id])
          redirect_to(root_url) unless current_user?(@user) || current_user.admin?
        end
        
        # Confirms that a user is logged-in
        def logged_in_user
          unless logged_in?
            flash[:danger] = "Please log in."
            redirect_to login_url
          end
        end
    
        # Below are several methods used in the above two..
    
        # Logs in the given user.
        def log_in(user)
          session[:user_id] = user.id
        end        
    
        # Returns true if the given user is the current user.
        def current_user?(user)
          user == current_user
        end
    
        # Returns the user corresponding to the remember token cookie.
        def current_user
          if (user_id = session[:user_id])
            @current_user ||= User.find_by(id: user_id)
          elsif (user_id = cookies.signed[:user_id])
            user = User.find_by(id: user_id)
            if user && user.authenticated?(:remember, cookies[:remember_token])
              log_in user
              @current_user = user
            end
          end
        end
    
        # Returns true if the user is logged in, false otherwise.
        def logged_in?
          !current_user.nil?
        end
    

    如果您仔细查看控制器文件的顶部,您会发现before_action 这是一个命令,它安排在允许发生给定操作之前调用特定方法。

    所以,在before_action :correct_user, only: [:edit, :update] 行内,我要求 Rails 做的是在更新或编辑用户信息之前检查用户是否正确。

    根据我对correct_user的定义...

    def correct_user
        @user = User.find(params[:id])
        redirect_to(root_url) unless current_user?(@user) || current_user.admin?
    end
    

    ...正确的用户是持有此帐户的用户或管理员。结果不会将我重定向到根页面,而是让我编辑用户的问题页面。

    希望对你有所帮助。

    更新:

    当管理员编辑用户信息时,他们不必知道密码即可。这是否以某种方式在您的代码中实现,或者如何绕过它?

    首先,我实际上看不到密码,因为它存储为摘要,然而如果您甚至不想让管理员编辑密码,那么你应该做的是以下......

    在您的 edit.html.erb 中,只需将密码字段放在 if 语句中...

    <% if !current_user.admin? %>
    
        <%= f.label :password %>
        <%= f.password_field :password %>
    
        <%= f.label :password_confirmation, "Confirmation" %>
        <%= f.password_field :password_confirmation %>
    
    <% end %>
    

    ...正是这样做的。

    如果我想查看用户信息安全的证据,我们可以查看控制台...

    2.2.1 :001 > User.first
      User Load (0.5ms)  SELECT  "users".* FROM "users"  ORDER BY "users"."id" ASC LIMIT 1 OFFSET 1
     => #<User id: 1, name: "Fake User", email: "fake@fakemail.org", created_at: "2015-07-11 18:36:00", updated_at: "2015-07-11 18:36:00", password_digest: "$2a$10$RpVWwRKWIQObTDow3PLGWOgjxqNNK.LU8p.fEPOVVnT...", remember_digest: nil, admin: nil, activation_digest: "$2a$10$jUZiRIiiBnpCSEv0h/KKi.fqdW3hVn94XFxxQS.n62X...", activated: true, activated_at: "2015-07-11 18:36:00", reset_digest: nil, reset_sent_at: nil> 
    

    【讨论】:

    • 这实际上很有意义,当然比我预期的要容易。只是一个额外的问题:当管理员编辑用户信息时,他们不必知道密码即可。这是否以某种方式在您的代码中实现,或者如何绕过它?
    • 是的,乔,我将简要更新我的帖子,让您了解如何操作。虽然,我永远无法看到任何人的密码,因为它存储为散列摘要。
    • 谢谢 - 确实如此。在不知道用户密码的情况下,需要实施额外的代码。对于用户,我要求他们输入当前密码以进行更改。显然管理员不能有同样的优先级。
    • 当然!天哪,我真傻=P完美,你的帮助是无价的,我真的很感激。谢谢。
    • 很高兴它帮到了你!万事如意
    【解决方案2】:

    我建议你查看 active_admin,你可以很容易地做到这一点。

    对于 rails 4,你只需要使用 master 分支。

    gem 'activeadmin', github: 'activeadmin'
    

    欲了解更多信息see docs here

    【讨论】:

    • 我以前听说过这个 gem,但如前所述,我宁愿不使用 gem,除非真的需要它。据我所知,可以在不添加其他宝石的情况下做到这一点吗?我对在一个项目中拥有太多宝石犹豫不决。
    • 如果您想要管理员部分来编辑用户信息,那么如果您只希望管理员能够在用户编辑页面上编辑用户,那么活动管理员是一个不错的选择,那么您不需要它,但是随着您的应用程序的增长,拥有一个专门的管理部分将使事情变得易于管理,您也可以向其中添加其他对象并使它们易于管理
    • 你是对的,我在做研究时在很多领域都读过。不过现在,我不知道是否会发生这种先进的情况。如果将来确实如此,那么我将重新访问(我知道以后很难更改),但同样,如果永远不需要它,我也不想继续使用这个宝石。非常感谢您的意见 =)
    猜你喜欢
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    • 1970-01-01
    相关资源
    最近更新 更多