Rails 可以在多个 table 中引用用户 table 中的枚举角色列吗?
Rails can a enum role column in User table be referenced in multiple tables?
我有一个带有角色属性的用户模型,我使用枚举定义了它。
enum role: {'Instructor': 0, 'Student': 1, 'Other': 2}
现在,我有另一位 table 讲师,来自用户 table。
我有一门课程 table 有讲师的参考资料。
我只希望讲师创建课程,不需要任何其他角色。
我正在使用 Pundit 进行授权。我在创建新课程时遇到问题。
def create
...
authorize @course
@course.instructor = Instructor.where(user: current_user).first
以上查询正在回滚但不保存课程。
任何建议都会有更大的帮助。
app/policies/course_policy.rb
Rollback Error
app/policies/course_policy.rb
class CoursePolicy < ApplicationPolicy
attr_reader :user, :model
def initialize (user, model)
@user = user
@course = model
end
def index?
true
end
def show?
true
end
def create?
@user.Instructor?
end
def update?
@user.Instructor_of? @course
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
scope.all
end
end
end
回滚错误输出:
ActiveRecord::AssociationTypeMismatch (Instructor(#70064238051700) expected, got #<ActiveRecord::Relation []> which is an instance of Instructor::ActiveRecord_Relation(#70064238083180)):
app/controllers/courses_controller.rb:31:in `create'
Started POST "/courses" for ::1 at 2019-04-13 06:02:33 +0700
Processing by CoursesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"++6oBiY4MeOHZKyMwAJ8VqF9ACayve5e+cmMg7FqG4dbHVCfDpI3uqVK7g75+auf8OABUTEnXlm9jshWu/50EQ==", "course"=>{"name"=>"Ruby on Rails", "description"=>"jk.jlliyf", "start_date(1i)"=>"2019", "start_date(2i)"=>"4", "start_date(3i)"=>"12", "end_date(1i)"=>"2019", "end_date(2i)"=>"7", "end_date(3i)"=>"12"}, "commit"=>"Create Course"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [["id", 2], ["LIMIT", 1]]
↳ /home/sagar/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
Instructor Load (1.8ms) SELECT "instructors".* FROM "instructors" WHERE "instructors"."user_id" = ORDER BY "instructors"."id" ASC LIMIT [["user_id", 2], ["LIMIT", 1]]
↳ app/controllers/courses_controller.rb:31
(0.4ms) BEGIN
↳ app/controllers/courses_controller.rb:34
(0.4ms) ROLLBACK
↳ app/controllers/courses_controller.rb:34
Rendering courses/new.html.erb within layouts/application
Rendered courses/_form.html.erb (44.0ms)
Rendered courses/new.html.erb within layouts/application (46.7ms)
Completed 200 OK in 267ms (Views: 124.6ms | ActiveRecord: 32.4ms)
课程模型:
app/models/course.rb
class Course < ApplicationRecord
belongs_to :instructor
end
根据评论线程,似乎没有必要使用 Instructor
模型。
因为在您的策略中,您已经将 create
操作限制为具有 Instructor
角色的 user
,并且您从不期望 Instructor
具有属性超过 user_id
,那么我想我会做:
def create
...
authorize @course
@course.instructor = current_user
...
end
现在,我打赌 Course
有 instructor_id
,而不是 user_id
。但是,没关系。您只需要做:
class Course << ApplicationRecord
belongs_to :instructor, class_name: 'User' # or whatever your user class name is.
...
end
现在您将能够做到:
@course.instructor
并取回作为课程讲师的 User
。
我还打赌 Instructor has_many :courses
通常允许您执行以下操作:
@instructor.courses
所以,您需要做的是:
class User << ApplicationRecord
has_many :instructed_courses, class_name: 'Course', foreign_key: :instructor_id
...
end
现在您可以执行以下操作:
@user.instructed_courses
current_user.instructed_courses
我正在做 "instructed_courses" 因为据推测,具有 Student
角色的 User
会想要做类似的事情:
@user.enrolled_courses
要做到这一点,我想我会创建:
class StudentCourse < Application
belongs_to :enrolled_course, class_name: 'Course'
belongs_to :student, class_name: 'User'
end
然后:
class User << ApplicationRecord
has_many :instructed_courses, class_name: 'Course', foreign_key: :instructor_id
has_many :student_courses, foreign_key: :student_id
has_many :enrolled_courses, through: :student_courses
...
end
现在你应该可以做到:
@user.enrolled_courses
current_user.enrolled_courses
您可能还想做类似的事情:
class Course << ApplicationRecord
belongs_to :instructor, class_name: 'User' # or whatever your user class name is.
has_many :student_courses, foreign_key: :enrolled_course_id
has_many :students, through: :student_courses
...
end
这样你就可以做到:
@course.students
沙赞!
我有一个带有角色属性的用户模型,我使用枚举定义了它。
enum role: {'Instructor': 0, 'Student': 1, 'Other': 2}
现在,我有另一位 table 讲师,来自用户 table。
我有一门课程 table 有讲师的参考资料。
我只希望讲师创建课程,不需要任何其他角色。
我正在使用 Pundit 进行授权。我在创建新课程时遇到问题。
def create
...
authorize @course
@course.instructor = Instructor.where(user: current_user).first
以上查询正在回滚但不保存课程。
任何建议都会有更大的帮助。
app/policies/course_policy.rb
Rollback Error
app/policies/course_policy.rb
class CoursePolicy < ApplicationPolicy
attr_reader :user, :model
def initialize (user, model)
@user = user
@course = model
end
def index?
true
end
def show?
true
end
def create?
@user.Instructor?
end
def update?
@user.Instructor_of? @course
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
scope.all
end
end
end
回滚错误输出:
ActiveRecord::AssociationTypeMismatch (Instructor(#70064238051700) expected, got #<ActiveRecord::Relation []> which is an instance of Instructor::ActiveRecord_Relation(#70064238083180)):
app/controllers/courses_controller.rb:31:in `create'
Started POST "/courses" for ::1 at 2019-04-13 06:02:33 +0700
Processing by CoursesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"++6oBiY4MeOHZKyMwAJ8VqF9ACayve5e+cmMg7FqG4dbHVCfDpI3uqVK7g75+auf8OABUTEnXlm9jshWu/50EQ==", "course"=>{"name"=>"Ruby on Rails", "description"=>"jk.jlliyf", "start_date(1i)"=>"2019", "start_date(2i)"=>"4", "start_date(3i)"=>"12", "end_date(1i)"=>"2019", "end_date(2i)"=>"7", "end_date(3i)"=>"12"}, "commit"=>"Create Course"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [["id", 2], ["LIMIT", 1]]
↳ /home/sagar/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
Instructor Load (1.8ms) SELECT "instructors".* FROM "instructors" WHERE "instructors"."user_id" = ORDER BY "instructors"."id" ASC LIMIT [["user_id", 2], ["LIMIT", 1]]
↳ app/controllers/courses_controller.rb:31
(0.4ms) BEGIN
↳ app/controllers/courses_controller.rb:34
(0.4ms) ROLLBACK
↳ app/controllers/courses_controller.rb:34
Rendering courses/new.html.erb within layouts/application
Rendered courses/_form.html.erb (44.0ms)
Rendered courses/new.html.erb within layouts/application (46.7ms)
Completed 200 OK in 267ms (Views: 124.6ms | ActiveRecord: 32.4ms)
课程模型:
app/models/course.rb
class Course < ApplicationRecord
belongs_to :instructor
end
根据评论线程,似乎没有必要使用 Instructor
模型。
因为在您的策略中,您已经将 create
操作限制为具有 Instructor
角色的 user
,并且您从不期望 Instructor
具有属性超过 user_id
,那么我想我会做:
def create
...
authorize @course
@course.instructor = current_user
...
end
现在,我打赌 Course
有 instructor_id
,而不是 user_id
。但是,没关系。您只需要做:
class Course << ApplicationRecord
belongs_to :instructor, class_name: 'User' # or whatever your user class name is.
...
end
现在您将能够做到:
@course.instructor
并取回作为课程讲师的 User
。
我还打赌 Instructor has_many :courses
通常允许您执行以下操作:
@instructor.courses
所以,您需要做的是:
class User << ApplicationRecord
has_many :instructed_courses, class_name: 'Course', foreign_key: :instructor_id
...
end
现在您可以执行以下操作:
@user.instructed_courses
current_user.instructed_courses
我正在做 "instructed_courses" 因为据推测,具有 Student
角色的 User
会想要做类似的事情:
@user.enrolled_courses
要做到这一点,我想我会创建:
class StudentCourse < Application
belongs_to :enrolled_course, class_name: 'Course'
belongs_to :student, class_name: 'User'
end
然后:
class User << ApplicationRecord
has_many :instructed_courses, class_name: 'Course', foreign_key: :instructor_id
has_many :student_courses, foreign_key: :student_id
has_many :enrolled_courses, through: :student_courses
...
end
现在你应该可以做到:
@user.enrolled_courses
current_user.enrolled_courses
您可能还想做类似的事情:
class Course << ApplicationRecord
belongs_to :instructor, class_name: 'User' # or whatever your user class name is.
has_many :student_courses, foreign_key: :enrolled_course_id
has_many :students, through: :student_courses
...
end
这样你就可以做到:
@course.students
沙赞!