sql – Rails与子类的STI关联
在使用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中找到的,但这会在控制器中产生问题,如果我想做branch.employees.build那么该类将默认为User,我必须在某处修改type列.我现在已经解决了这个问题: 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,通过:: branches将再次只在选择中包含User :: Employee类. 解决方法基本上,该问题仅存在于根据需要加载类的开发环境中. (在生产中,类被加载并保持可用.)问题来自于,当您第一次运行Employee.find等调用时,解释器还没有看到Admins是一种Employee. (请注意,它稍后使用IN(‘User :: Employee’,’User :: BranchAdmin’)) 每次使用深度超过一级的模型类时都会发生这种情况,但仅限于开发模式. 子类始终自动加载其父层次结构.基类不会自动加载他们的子级别. 哈克修复: 您可以通过显式要求基类rb文件中的所有子类来强制在dev模式下执行正确的行为. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- SqlServer 您对无法重新创建的表进行了更改或者启用了 阻止
- sql – NULL值被排除.为什么?
- sql-server – Entity Framework 4与LINQ to SQL,适用于使用
- SQL Server 2005的output子句用法
- 数据库设计 – 在具有缩写表名的表中为每个字段名添加前缀是
- 数据库 – 为什么他们使用DBMS_STATS.GATHER_TABLE_STATS?
- 非本地数据库上的liquibase模式对话框
- bcp of sqlserver
- 在 本地计算机 无法启动 MSSQLSERVER 服务。错误 3: 系统找
- sql – 确定ORACLE表中是否存在字段的快速方法