Activerecord 为什么ARel作用域在使用联接时变为只读?

Activerecord 为什么ARel作用域在使用联接时变为只读?,activerecord,arel,Activerecord,Arel,如果在ARel作用域中使用联接,则结果将变为只读(即,您无法更新返回的任何记录)。如果不希望结果是只读的,只需将readonly(false)链接到范围,例如 User.joins(:orders).where(:orders=>{:state=>'completed'}).只读(false) 但是我猜,连接作用域默认为只读是有原因的。将结果设置为只读的原因是什么?有趣的问题。我在谷歌上搜索了一下……通过一个连接查询,您将返回一条带有User+order表属性的记录。如果试图更新order表

如果在ARel作用域中使用
联接
,则结果将变为只读(即,您无法更新返回的任何记录)。如果不希望结果是只读的,只需将
readonly(false)
链接到范围,例如


User.joins(:orders).where(:orders=>{:state=>'completed'}).只读(false)


但是我猜,连接作用域默认为只读是有原因的。将结果设置为只读的原因是什么?

有趣的问题。我在谷歌上搜索了一下……通过一个连接查询,您将返回一条带有User+order表属性的记录。如果试图更新order表中的一个属性(例如“order_num”)而不是用户表,则用户表的update语句将无法找到order_num,并将崩溃。因此,连接作用域在默认情况下是只读的,以防止发生这种情况

参考资料: 1)

2)

据我所知,
SELECT
查询只返回用户属性,而不是订单属性,因为它正在执行
selectusers.*FROM…
。因此,据我所知,返回的ActiveRecord对象不应该包含任何order属性,我还看到它只返回原始模型的内容。这使得在默认范围内使用联接变得困难。我在默认范围内使用联接,根据层次模型生态系统过滤非活动记录(例如,如果订单为“非活动”,则默认情况下不应返回订单行。因此,订单行默认范围{joins(:Order)}和订单默认范围{where(active:true)}。