用户的Ruby on Rails角色

时间:2017-11-02 12:09:57

标签: ruby-on-rails ruby model authorization

我有以下问题。我正在用tutorial从头开始编写授权书。但在本教程中,用户角色具有布尔类型。我的模型user_role有字符串类型。我想这样做,如果你有user_role == 'admin',你可以随处访问。如果您有user_role == 'user',则只能访问动作节目和索引。

我已经在代码文件名后添加了模型:

permission.rb

class Permission < Struct.new(:user)

  def allow?(controller, action)
    if user.user_role == "user"
    controller == "posts" && action.in? == (%w[index show])
  elsif user.user_role == "admin"
      true
    end
  end
end

当我点击我的页面中的编辑时出现错误:

  PostsController中的 NoMethodError#编辑未定义的方法`user_role&#39;对于   零:NilClass

我该如何解决?

我模特的一部分

  create_table "posts", force: :cascade do |t|
    t.string "title"
    t.text "content"
    t.boolean "read"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.date "creation_date"
    t.string "author"
    t.integer "user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer "sign_in_count", default: 0, null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string "current_sign_in_ip"
    t.string "last_sign_in_ip"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "user_role"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

我的应用程序控制器

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :authorize, only: [:new, :edit, :update, :destroy, :update ]

#  def after_sign_in_path_for(resource)
#    app_dashboard_index_path
#end
private

def current_user
  @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
end


def current_permission
  @current_permission ||= Permission.new(current_user)
end

def authorize
  if !current_permission.allow?(params[:controller], params[:action])
    redirect_to posts_path, alert: "Not authorized"
  end
end

MY Post Controller

class PostsController < ApplicationController
  before_action :find_post, only: [:show, :edit, :update, :destroy]
  before_action :authorize, only: [:new, :edit, :update, :destroy, :update ]


  def index
    @posts = Post.all
  end

  def edit
  end

  def new
    @post =  current_user.posts.new
  end

  def show
  end

  def update
    if @post.update_attributes(post_params)
      flash[:notice] = "Data has hanged"
      redirect_to post_path
    else
      render action 'edit'
    end
  end

  def destroy
    @post.destroy
    redirect_to posts_path
  end

  def create
    @post = current_user.posts.build(post_params)

    if @post.save
      redirect_to @post
    else
      render 'index'
    end
  end

private

def find_post
  @post = Post.find(params[:id])
end

def post_params
  params.require(:post).permit(:title, :content, :read, :author)
end


end

(之前我曾尝试过使用gem CanCanCan和Pundit进行授权,但我并不了解它是如何工作的,所以我从项目中删除它们。)

1 个答案:

答案 0 :(得分:0)

NoMethodError in PostsController#edit undefined method `user_role' for nil:NilClass

这意味着你试图在一个对象上调用'user_role',并且该对象在不应该的时候是nil。我猜你的Permission类没有用户定义。无论哪种方式,我都会以不同的方式接近它:

class PostsController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :authorize, skip: [:show, :index]

  def authorize
    return if current_user && current_user.user_role == 'admin'
    redirect_to posts_path, alert: 'You are not allowed to access this part of the site'
  end
end

除了show和index之外,这将在posts控制器的每个动作中调用authorize方法。

如果用户已登录且其user_role为“admin”,则该方法将返回并且不执行任何操作。否则它将重定向到帖子路径。