rails_admin根据角色过滤数据

时间:2017-10-11 07:07:26

标签: ruby-on-rails ruby-on-rails-4 cancan rails-admin cancancan

我的rails_admin应用程序有两个角色,即TeacherStudent,以便每个用户belongs_to都有一个角色。我正在使用gem cancancan来管理角色。

应用程序/模型

class Role < ApplicationRecord
    has_many :users
end

class User < ApplicationRecord
    belongs_to :role
    has_many :projects
end

class Project < ApplicationRecord
    belongs_to :user
end

Project架构

create_table "projects", force: :cascade do |t|
    t.string   "name"
    t.string   "description"
    t.integer  "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["user_id"], name: "index_projects_on_user_id", using: :btree
  end

现在,我希望项目列表在roleTeacher时显示所有数据,但只应在project.user_id == user.id为{role时显示Student的项目1}}。

也就是说,最终目标是允许role Student仅查看他/她自己的项目,从而限制role Student查看所有项目因为role Teacher应该能够看到所有项目。

5 个答案:

答案 0 :(得分:1)

要根据当前user角色获取数据,我对models/ability.rb进行了以下更改。

在用户roleStudent

的情况下
can :read, Project, ["user_id = ?", user.id] do |project|
    project.present?
end

它会将user_id表中的projectsuser.id进行比较,因此,对于role Student,它只会获取由此创建的项目学生。

答案 1 :(得分:0)

您的控制器将有一个列出项目的动作。 只需使用before_action过滤器即可根据角色加载项目。 假设您在应用程序的基本控制器中设置current_user,并且与学生和项目 - 学生has_many项目有关联。

ProjectController
  before_action :load_projects, only: [:index]

  def index
    @projects
  end

  private
  def load_projects
    if current_user.role == "Teacher"
      @projects = Project.all
    elsif current_user.role == "Student"
      @projects = current_user.projects
    end
  end
end

您还可以添加项目和教师之间的关联。如果您需要,还可以使用teacher.projects

答案 2 :(得分:0)

还有另一种实现功能的方法

在用户表中创建一个名为role的新列

     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.integer  "role"
        t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
        t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
      end

在用户模型中

     class User < ApplicationRecord

      enum role: [:student, :teacher, ]
      after_initialize :set_default_role, :if => :new_record?

     def set_default_role
     self.role ||= :student
     end

     end

当新用户注册时,这将创建一个默认角色作为学生。您可以通过简单地将用户的角色更改为教师

使用终端转到rails console    rails c

  u = User.find_by_id(1) 
  # you can change value '1' depending upon your user_id
  u.role = "teacher"
  u.save

现在用户的角色是老师。

  class ProjectsController < ApplicationController

  if current_user.teacher?
    @projects = Project.all
  else
    @project = current_user.projects
  end

答案 3 :(得分:0)

class User < ApplicationRecord
    belongs_to :role
    has_many :projects

    def projects
        if self.role.to_s == "student"
            super projects
        else
            Project.all
        end
    end
end

答案 4 :(得分:0)

提供的答案可以更改控制器,并且提问者指出他无法访问控制器。

不确定cancancan是否会根据对rails admin的索引视图的查看(读取)权限来处理对记录的过滤,其规则如下:

can :read, Project, user_id: user.id

但是在编辑视图中,我知道您可以根据当前用户配置一个包含多个字段的范围,如下所示:

    edit do
      field :projects do
        associated_collection_scope do
          current_user = bindings[:controller].current_user
          proc { |scope| scope.where(user: current_user) }
        end
      end
    end
相关问题