覆盖默认的STI行为

时间:2015-10-07 22:58:14

标签: ruby-on-rails

我有配置文件的STI设置。配置文件可以是用户或页面,但是有许多类型的用户和配置文件。例如:

profile
  -user
    --member
    --admin
    --moderator
  -page
    --business
    --event
    --band

当我尝试运行查询时

Profile::User.find_by_email(params[:email])

生成的SQL

SELECT  "profiles".* FROM "profiles" WHERE "profiles"."type" IN ('Profile::User') AND "profiles"."email" = 'email@email.com' LIMIT 1

由于存在不同类型的用户,因此该查询无效。

是否可以覆盖默认的“IN”行为,以便不是搜索基本的Profile :: User,而是可以包含不同类型的用户?换句话说,我想生成

 SELECT  "profiles".* FROM "profiles" WHERE "profiles"."type" IN ('Profile::User::Member', 'Profile::User::Admin', 'Profile::User::Moderator') AND "profiles"."email" = 'email@email.com' LIMIT 1

1 个答案:

答案 0 :(得分:2)

it has a separate section in the guides实际上是一个常见的问题。

问题在于持续自动加载。它查询当前知道的User 的所有后代。当急切加载(例如在production环境中)时, 工作。否则,只会在引用它们的地方查找和加载类。你从不在父母中引用孩子,因此他们没有加载,也没有在后代列表中结束。

指南中的部分提出了一个解决方案:要求"底部"带有基类的文件中带有require_dependency的层次结构(STI层次结构的根)。因为事实证明,父类 需要知道它的子节点才能找到它们。

  

只需要加载至少孙子的树叶   办法。直接子类不需要预加载。如果是层次结构   更深层次,中间类将从递归自动加载   底部因为它们的常量会出现在类定义中   作为超类。

也就是说,自动加载可以轻松处理上行" up"在层次结构中,但不能" down"。通过加载"底部"自动加载可以递归地跟随父类,并发现其他类。

指南声称此行为不是错误。但是,它确实是一个异常现象。