rails_admin 根据角色过滤数据

rails_admin filter data based on role

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

app/models

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 时显示所有数据,但当 roleproject.user_id == user.id 时,它应该只显示那些项目Student

即最终目的是让roleStudent只能看到his/her自己的项目从而限制roleStudent看到role Teacher 应该可以看到所有项目的所有项目。

您的控制器将具有列出项目的操作。 只需使用 before_action 过滤器即可根据角色加载项目。 假设您在应用程序的基本控制器中设置 current_user 并且关联 b/w 学生和项目 - 学生 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

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

在用户中创建一个名为角色的新列 table

     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

这会在新用户登录时创建一个默认角色作为学生 up.you 只需执行以下操作即可将用户的角色更改为教师

在终端中使用 rails 转到控制台 railsc

  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
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

所提供的答案假设控制器可以更改,并且由于提问者指出他无法访问它们。

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

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

为了根据当前 user 角色获取数据,我对 models/ability.rb.

进行了以下更改

在用户roleStudent

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

它将比较 projects table 中的 user_iduser.id 因此,在 role Student 的情况下,它只会获取该学生创建的项目。