【问题标题】:Rails 4 with PunditRails 4 与 Pundit
【发布时间】:2015-12-14 01:20:30
【问题描述】:

我正在尝试在 Rails 4 中制作应用程序。

我想使用 Pundit 进行授权。我还使用 Devise 进行身份验证,使用 Rolify 进行角色管理。

我有一个用户模型,我正在制定我的第一个策略,遵循本教程:

https://www.youtube.com/watch?v=qruGD_8ry7k

我有一个用户控制器:

    class UsersController < ApplicationController

before_action :set_user, only: [:index, :show, :edit, :update, :destroy]

  def index
    if params[:approved] == "false"
      @users = User.find_all_by_approved(false)
    else
      @users = User.all
    end

  end

  # GET /users/:id.:format
  def show
    # authorize! :read, @user
  end

  # GET /users/:id/edit
  def edit
    # authorize! :update, @user
  end

  # PATCH/PUT /users/:id.:format
  def update
    # authorize! :update, @user
    respond_to do |format|
      if @user.update(user_params)
        sign_in(@user == current_user ? @user : current_user, :bypass => true)
        format.html { redirect_to @user, notice: 'Your profile was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  # GET/PATCH /users/:id/finish_signup
  def finish_signup
    # authorize! :update, @user 
    if request.patch? && params[:user] #&& params[:user][:email]
      if @user.update(user_params)
        @user.skip_reconfirmation!
        sign_in(@user, :bypass => true)
        redirect_to @user, notice: 'Your profile was successfully updated.'
      else
        @show_errors = true
      end
    end
  end

  # DELETE /users/:id.:format
  def destroy
    # authorize! :delete, @user
    @user.destroy
    respond_to do |format|
      format.html { redirect_to root_url }
      format.json { head :no_content }
    end
  end

  private
    def set_user
      @user = User.find(params[:id])
    end

    def user_params
      params.require(:user).permit(policy(@user).permitted_attributes)
      # accessible = [ :first_name, :last_name, :email ] # extend with your own params
      # accessible << [ :password, :password_confirmation ] unless params[:user][:password].blank?
      # accessible << [:approved] if user.admin
      # params.require(:user).permit(accessible)
    end

end

这是我第一次尝试用户政策。

class UserPolicy < ApplicationPolicy


  def initialize(current_user, user)
    @current_user = current_user
    @user = user

  end

  def index?
    @current_user.admin? 
  end

  def show?
    @current_user.admin? 
  end

  def edit?
    @current_user.admin? 
  end

  def update?
    @current_user.admin?  
  end

  def finish_signup?
    @current_user = @user
  end

  def destroy?
    return false if @current_user == @user
    @current_user.admin? 
  end

private
  def permitted_attributes
      accessible = [ :first_name, :last_name, :email ] # extend with your own params
      accessible << [ :password, :password_confirmation ] unless params[:user][:password].blank?
      accessible << [:approved] if user.admin
      params.require(:user).permit(accessible)
  end

end

我的问题是:

  1. 本教程显示了名为 attr_reader 的内容。我已经从 rails 4 开始学习 rails,所以我不知道这些词是什么意思。我认为这与在控制器中将用户参数列入白名单的旧方式有关,所以我认为我不需要将其包含在我的用户策略中。对吗?

  2. 我必须按照上面的方式初始化用户模型是否正确(或者只有在用户以外的模型中才会出现这种情况,因为我正在初始化 current_user,它可能已经让用户初始化了?

  3. 是否有必要将强参数移动到策略中,或者如果我将它们留在控制器中,这会起作用吗?

【问题讨论】:

    标签: ruby-on-rails devise pundit


    【解决方案1】:
    1. 本教程显示了名为 attr_reader 的内容。我已经从 rails 4 开始学习 rails,所以我不知道这些词是什么意思。我认为这与在控制器中将用户参数列入白名单的旧方式有关,所以我认为我不需要将其包含在我的用户策略中。对吗?

    不,这很重要。

    attr_reader 创建实例变量和返回每个实例变量值的相应方法。 - 来自 Ruby 官方文档

    如果你这样做了

    class A
       attr_reader :b
    end
    
    a = A.new
    

    您可以通过a.b 访问b 实例变量。这很重要,因为在每个策略中,您都可能允许 read 访问实例变量。 @current_user@user 是实例变量。

    1. 我必须按照上面的方式初始化用户模型是否正确(或者只有在用户以外的模型中才会出现这种情况,因为我正在初始化 current_user,它可能已经初始化了用户?

    您必须手动初始化它。目前,您的做法是正确的。好的。

    1. 是否有必要将强参数移动到策略中,或者如果我将它们留在控制器中,这会起作用吗?

    这是选择的问题。即使您将其保存在控制器中,它也会起作用。仅当您想以非常复杂的方式将属性列入白名单时才使用策略。

    注意:devicepunditrolify gem 效果很好,但它们共享一些相同的功能,所以要小心并保持一致。

    例如,您可以使用devise_for :users , :students , :teachers,它将提供 3 个不同的链接来登录相应的资源。你可以用它做很多事情。您可以使用 authenticate 方法根据资源进一步验证 url。检查https://github.com/plataformatec/devise/wiki/How-To:-Define-resource-actions-that-require-authentication-using-routes.rb 这种事情也可以用punditrolifyroles 来完成。

    【讨论】:

    • 谢谢。 13 个小时,直到我可以把赏金点放在这个上面。你对共享功能是什么意思。我想让我的专家说如果用户是学生然后编辑项目(然后强参数被列入白名单,所以如果用户是学生他们可以访问项目字段)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多