当前位置:  开发笔记 > 后端 > 正文

Rails:即使不需要,也可以在连接上使用.references

如何解决《Rails:即使不需要,也可以在连接上使用.references》经验,为你挑选了1个好方法。

我知道当你使用includeswhere在连接表上指定一个子句时,你应该使用.references

例:

# will error out or throw deprecation warning in logs
customers = Customer.includes(:orders).where("Orders.cost < ?", 100)

否则,在rails 4或更高版本中,您将收到如下错误:

Mysql2 ::错误:'where子句'中的未知列'Orders.cost':SELECT customers.*FROM customersWHERE(Orders.cost <100)

或者您将收到弃用警告:

弃用警告:您似乎急于加载在字符串SQL片段中引用的表(用户,地址之一).例如:

Post.includes(:comments).where("comments.title = 'foo'")

目前,Active Record识别字符串中的表,并且知道将comments表连接到查询,而不是在单独的查询中加载注释.但是,在不编写完整的SQL解析器的情况下执行此操作本身就存在缺陷.由于我们不想编写SQL解析器,因此我们将删除此功能.从现在开始,当您从字符串引用表时,必须明确告诉Active Record:

Post.includes(:comments).where("comments.title ='foo'").references(:comments)

如果您不依赖隐式连接引用,则可以通过设置完全禁用该功能config.active_record.disable_implicit_join_references = true.(

SELECT"users"."id"AS t0_r0,"users"."name"AS t0_r1,"users"."email"AS t0_r2,"users"."created_at"AS t0_r3,"users"."updated_at"AS t0_r4 ,"地址"."id"AS t1_r0,"地址"."user_id"AS t1_r1,"地址"."country"AS t1_r2,"地址"."street"AS t1_r3,"地址"."postal_code"AS t1_r4 ,"地址"."city"AS t1_r5,"地址"."created_at"AS t1_r6,"地址"."updated_at"AS t1_r7 FROM"users"LEFT OUTER JOIN"地址"ON"地址"."user_id"="用户"."id"WHERE(addresses.country ='Poland')

说得通.使用时,Rails不希望成为SQL解析器includes.因此,为了让铁路开心,我们这样做:

# No error and no deprecation warning because we are explicitly specifying what table is referenced within that where clause
customers = Customer.includes(:orders).where("Orders.cost < ?", 100).references(:orders)

但是,当您在连接表上使用joinswhere子句时:Rails不会出错,并且rails也不会像以下那样抛出弃用警告includes:

# No error and no deprecation warning.  What????
customers = Customer.joins(:orders).where("Orders.cost < ?", 100)

这对我来说没有意义.我认为如果rails不想成为SQL解析器includes,那么它也不希望成为一个SQL解析器joins.我认为rails会更喜欢我这样使用references:

customers = Customer.joins(:orders).where("Orders.cost < ?", 100).references(:orders)

所以我的问题:

    我错过了什么吗?它是精绝不指定referencesjoinswhere上连接表的条款,即使它是非常需要的includes?如果是这样的话:为什么includesjoins

    我应该指定referencesjoins向前迈进?也许一旦rails的SQL解析器消失了,所有那些在连接表上joinswhere子句的人将不再工作了?

charlysisto.. 6

在之间的根本区别joinsincludes(其是用于2种方法的包装:eager_loadpreload)是:

joins直截了当地执行SQ​​L并不加选择地返回所有记录

includes将确定哪些记录属于哪个模型并构建模型树: author1 -> [post, post, post], author2 -> [post, post]

例如,如果你加入,Order.joins(:product_items)你会得到:

所有ProductItem记录与Orders交织在一起.

而与Order.includes(:product_items)得到Orders与嵌套在每个相应的订单product_items.

因此reference,当您执行includes(或eager_loadpreload)帮助区分SQL连接中的数据并将其分配给正确的模型时,此处仅对Rails有用.

随着joins你在SQL世界中独自一人.大多数时候我会使用它group("orders.id")和一个聚合函数:

select(orders.*, count(product_items.id) as cart_size)...



1> charlysisto..:

在之间的根本区别joinsincludes(其是用于2种方法的包装:eager_loadpreload)是:

joins直截了当地执行SQ​​L并不加选择地返回所有记录

includes将确定哪些记录属于哪个模型并构建模型树: author1 -> [post, post, post], author2 -> [post, post]

例如,如果你加入,Order.joins(:product_items)你会得到:

所有ProductItem记录与Orders交织在一起.

而与Order.includes(:product_items)得到Orders与嵌套在每个相应的订单product_items.

因此reference,当您执行includes(或eager_loadpreload)帮助区分SQL连接中的数据并将其分配给正确的模型时,此处仅对Rails有用.

随着joins你在SQL世界中独自一人.大多数时候我会使用它group("orders.id")和一个聚合函数:

select(orders.*, count(product_items.id) as cart_size)...

推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有