gpt4 book ai didi

sql - Rails STI 与子类的关联

转载 作者:行者123 更新时间:2023-12-04 09:26:45 25 4
gpt4 key购买 nike

使用 STI 时,从与 rails 3 的 has_many 关联中获取集合时,我遇到了一些奇怪的行为。我有:

class Branch < ActiveRecord::Base
has_many :employees, class_name: 'User::Employee'
has_many :admins, class_name: 'User::BranchAdmin'
end

class User < ActiveRecord::Base
end

class User::Employee < User
belongs_to :branch
end

class User::BranchAdmin < User::Employee
end

所需的行为是 branch.employees返回所有员工,包括分行管理员。当 branch.admins 访问分支管理员时,它们似乎只在此集合下“加载”。 ,这是控制台的输出:
Branch.first.employees.count
=> 2

Branch.first.admins.count
=> 1

Branch.first.employees.count
=> 3

这可以在生成的SQL中看到,第一次:
SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee') AND "users"."branch_id" = 1

第二次:
SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee', 'User::BranchAdmin') AND "users"."branch_id" = 1

我可以通过指定来解决这个问题:
class Branch < ActiveRecord::Base
has_many :employees, class_name: 'User'
has_many :admins, class_name: 'User::BranchAdmin'
end

因为它们都可以从他们的 branch_id 中找到,但是如果我想做的话,这会在 Controller 中产生问题 branch.employees.build那么该类将默认为 User我必须在某处修改类型列。我现在已经解决了这个问题:
  has_many :employees, class_name: 'User::Employee', 
finder_sql: Proc.new{
%Q(SELECT users.* FROM users WHERE users.type IN ('User::Employee','User::BranchAdmin') AND users.branch_id = #{id})
},
counter_sql: Proc.new{
%Q(SELECT COUNT(*) FROM "users" WHERE "users"."type" IN ('User::Employee', 'User::BranchAdmin') AND "users"."branch_id" = #{id})
}

但如果可能的话,我真的很想避免这种情况。任何人,任何想法?

编辑:

finder_sql 和 counter_sql 并没有真正为我解决这个问题,因为似乎父协会不使用它,所以 organisation.employees那个 has_many :employees, through: :branches将再次只包含 User::Employee在选择类。

最佳答案

基本上,问题只存在于按需加载类的开发环境中。 (在生产中,类被加载并保持可用。)

问题出现是由于解释器还没有看到 AdminsEmployee 的类型当您第一次运行 Employee.find 时等调用。

(注意后面会用到 IN ('User::Employee', 'User::BranchAdmin') )

每次使用深度超过一层的模型类都会发生这种情况,但仅限于开发模式。

子类总是自动加载它们的父层次结构。基类不会自动加载其子层次结构。

黑客修复:

您可以通过明确要求基类 rb 文件中的所有子类来强制在开发模式下执行正确的行为。

关于sql - Rails STI 与子类的关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11118413/

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