我的rails_admin
应用程序有两个角色,即Teacher
和Student
,以便每个用户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
现在,我希望项目列表在role
为Teacher
时显示所有数据,但只应在project.user_id == user.id
为{role
时显示Student
的项目1}}。
也就是说,最终目标是允许role
Student
仅查看他/她自己的项目,从而限制role
Student
查看所有项目因为role
Teacher
应该能够看到所有项目。
答案 0 :(得分:1)
要根据当前user
角色获取数据,我对models/ability.rb
进行了以下更改。
在用户role
为Student
can :read, Project, ["user_id = ?", user.id] do |project|
project.present?
end
它会将user_id
表中的projects
与user.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