gpt4 book ai didi

ruby-on-rails - Active Record 包含 STI

转载 作者:行者123 更新时间:2023-12-03 16:06:15 29 4
gpt4 key购买 nike

我有以下型号

class Event < ActiveRecord::Base
has_many :attendances

class Attendance < ActiveRecord::Base
belongs_to :user

class Student < User
has_one :student_detail

class StudentDetail < ActiveRecord::Base
belongs_to :school

class Staff < User
has_one :staff_detail

class StaffDetail < ActiveRecord::Base

StudentDetail 和 StaffDetails 有附加信息,我试图避免将它们全部放在一个 STI 用户表中,因为必须使用类似于 的内容。每个表模式的具体类

我可以很容易地做到这一点
Event.includes(:attendances => :user).where(...)

但我希望能够根据用户类型包含
例如
Event.includes(attendances: {:user => :student_details })

这将失败,因为某些用户是 Staff 对象。

我意识到 Rails 不会开箱即用,但任何人都有任何技巧可以让它发挥作用

现在最好的解决方案是将用户与学生和教职员工的出勤分开
IE。
class Attendance < ActiveRecord::Base
belongs_to :student, -> {includes(:staff_detail) }
belongs_to :staff, -> {includes(:student_detail) }
#belong_to :user

这并不理想。
有人有任何提示吗?解决这个问题的方法。

最佳答案

最简单的方法是移动 has_one关联到用户。由于只有 Staff记录将有 staff_details ,预加载将正常工作。

class User < ActiveRecord::Base
has_one :staff_detail
has_one :student_detail
end

class Staff < User; end
class Student < User; end

但这并不理想。要进一步自定义预加载,您可以使用 Preloader Rails 中的类。首先,加载没有任何包含的所有记录,然后遍历它们并预加载您需要的关联:
events = Event.includes(:attendances => :user)
users = events.users.flatten
users.group_by(&:class).each do |klass, records|
associations = {
Staff: [:staff_detail],
Student: [:student_detail]
}.fetch(klass, [])

ActiveRecord::Associations::Preloader.new(records, associations).run
end

注意这个 API changed in Rails 4 .在版本 3 及更早版本中,您只使用了 preload_associations 方法。

前阵子我写了一个 blog post about this same problem其中包括一些其他巧妙的技巧(例如规范您获得正确的行为)。

关于ruby-on-rails - Active Record 包含 STI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27791253/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com