rails_admin 根据角色过滤数据
rails_admin filter data based on role
我的 rails_admin
应用程序有两个角色,即 Teacher
和 Student
这样每个用户 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
现在,我希望项目列表在 role
为 Teacher
时显示所有数据,但当 role
为 project.user_id == user.id
时,它应该只显示那些项目Student
。
即最终目的是让role
Student
只能看到his/her自己的项目从而限制role
Student
看到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
.
进行了以下更改
在用户role
为Student
的情况下
can :read, Project, ["user_id = ?", user.id] do |project|
project.present?
end
它将比较 projects
table 中的 user_id
与 user.id
因此,在 role
Student
的情况下,它只会获取该学生创建的项目。
我的 rails_admin
应用程序有两个角色,即 Teacher
和 Student
这样每个用户 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
现在,我希望项目列表在 role
为 Teacher
时显示所有数据,但当 role
为 project.user_id == user.id
时,它应该只显示那些项目Student
。
即最终目的是让role
Student
只能看到his/her自己的项目从而限制role
Student
看到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
.
在用户role
为Student
can :read, Project, ["user_id = ?", user.id] do |project|
project.present?
end
它将比较 projects
table 中的 user_id
与 user.id
因此,在 role
Student
的情况下,它只会获取该学生创建的项目。