目前,我知道在rails中进行子选择的唯一方法是使用arel, 例如-
sub = x.where(y:'x').project(:id)
select = a.where(a[:x_id].in(sub))
问题是,
如果x使用可在gem上标记的行为,并且需要通过特定标记进行过滤,请使用tagged_with
方法。
我仍然如何达到相同的数据库效率,好像tagged with
方法覆盖了投影。
谢谢
答案 0 :(得分:1)
您不需要Arel在Rails中构建子选择:
sub = X.where(y: 'x')
select = A.where(x_id: sub)
假设A的表名是as
,X的是xs
,则生成以下SQL:
SELECT "as".* FROM "as" WHERE "as"."x_id" IN (SELECT "xs"."id" FROM "xs" WHERE "xs"."y" = 'x')
使用tagged_with
进行测试是有效的:A.where(x_id: X.tagged_with('my_tag'))
至少在我测试过的Rails 5.1版本上生成了预期的SQL。
编辑
如果需要,您可以指定子选择内使用的列。如果未指定,则主键列为默认值:
sub = X.where(y: 'x').select(:x_y_id)
select = A.where(x_id: sub)
将生成以下SQL:
SELECT "as".* FROM "as" WHERE "as"."x_id" IN (SELECT "xs"."x_y_id" FROM "xs" WHERE "xs"."y" = 'x')