新手问题 Rails Model 中 has_one 关系如何加载 conditions

zxzllyj · 2016年04月05日 · 最后由 zxzllyj 回复于 2016年04月06日 · 2779 次阅读

如题: 遇上这样一个问题,存在三个表:user namespace group 其中,group 是单表继承的 namespace ,通过在其中,user 和 namespace 的对应关系为 has_one, user 与 group 的关系为 has_many 因为业务调整,先在需要将 namespace 中的 type 字段调整为 group,然后新增一个 namespace 给用户,就出现了这样一个问题:修改为 group 后 group 的 id 比 namespace 的 id 要小 这就导致通过关系查询 user 的 namespace 查找出的是 group 的问题,其生成的 sql 如下:

SELECT `namespaces`.* FROM `namespaces` WHERE `namespaces`.`id` = 用户id LIMIT 1

关系中指定了限制条件

has_one :namespace, dependent: :destroy, foreign_key: :owner_id, class_name: "Namespace", conditions: 'type IS NULL'

明显,限制条件 type is NULL 没有生效,但是,如果将 has_one 改为 has_many 限制条件就生效了

请问,如何才能是 has_one 的限制条件生效 通过 google 和查询文档,确定 conditions=>{:type=> nil}这样的写法支持但并未生效,该文档指定的 rails 版本为 3.2.13 注:我的 rails 版本是 3.2.16

has_one :namespace, -> { where(type: nil) }, dependent: :destroy, foreign_key: :owner_id, class_name: "Namespace"

楼上的写法是 4 以后的吧,3.2.16 好像还没有 v3.2.16/has_one 没有装 3 我用 4 的写法试了一遍没问题的,楼主要不再在 console 里检查一下

Namespace Load (0.3ms)  SELECT  "namespaces".* FROM "namespaces" WHERE "namespaces"."owner_id" = $1 AND "namespaces"."type" IS NULL LIMIT 1  [["owner_id", 2]]

#2 楼 @z_ach 对,我没有留意到他注明的版本是 3.2.16

#2 楼 @z_ach #3 楼 @hungyuhei 我在 rails c 上面试了很奇怪 我重启机子后执行出现两条 sql,如下:

Namespace Load (18.6ms)  SELECT `namespaces`.* FROM `namespaces` WHERE `namespaces`.`id` = ****** LIMIT 1
  Namespace Load (39.4ms)  SELECT `namespaces`.* FROM `namespaces` WHERE `namespaces`.`owner_id` = ****** AND `namespaces`.`type` IS NULL LIMIT 1

然后就找到正确的结果了,但是,我只是重启服务器,并没有重启机器时就只会出现第一条 sql 然后我查了一下文档,似乎 3.2 的 rails 是支持 conditions 的,但是不知为何没有生效

#4 楼 @zxzllyj 的确好奇怪。。第一条是按 id 查 namespace 的,直接 user.namespace 应该只有第二条才对,只有第一条的话会不会是没执行到 user.namespace 就报错了,还是 User 被重新定义了 namespace 方法。重启服务器对结果有影响这个就比较奇怪了。。。

#5 楼 @z_ach 刚刚重新在 rails c 里跑了一下,生成的 sql 是这个:

Namespace Load (8.2ms)  SELECT `namespaces`.* FROM `namespaces` WHERE `namespaces`.`owner_id` = 141089 LIMIT 1

限制条件还是没有加上去.... 我全文搜索了一下只在 namespace 下发现:

belongs_to :owner, class_name: "User"

然后再也没有看到别的了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号