Arel:与加入的Arel :: SelectManager之间的主动关系
问题描述:
让我们来看看Rails 4.2.x应用程序,我们有两个表格文章和作者,我们希望使用Arel来获取由作者创作的文章,其中name = ='卡尔'。 (在这种情况下,我们会很乐意与Active Record的加入,但是这仅仅是保持示例简单。)Arel:与加入的Arel :: SelectManager之间的主动关系
posts = Arel::Table.new :posts
authors = Arel::Table.new :authors
my_query = posts.project(Arel.star)
.join(authors)
.on(posts[:author_id].eq(authors[:id]))
.where(authors[:name].eq('Karl'))
> my_query.class
=> Arel::SelectManager
现在我们可以通过做回来数组(类数组)职位:
> Post.find_by_sql my_query
[master] Post Load (3.1ms) SELECT * FROM "posts" INNER JOIN "authors"
ON "posts"."author_id" = "authors"."id"
WHERE "authors"."name" = 'Karl'
=> [#<Post:0x005612815ebdf8
id: 7474,
...
]
所以我们得到桩的阵列,而不是一个有效记录的关系:
> Post.find_by_sql(my_query).class
=> Array
而且注射经理到Post.where将无法正常工作
> Post.where my_query
=> #<Post::ActiveRecord_Relation:0x2b13cdc957bc>
> Post.where(my_query).first
ActiveRecord::StatementInvalid: PG::SyntaxError:
ERROR: subquery must return only one column
SELECT "posts".* FROM "posts"
WHERE ((SELECT * FROM "posts" INNER JOIN "authors" ON "posts"."author_id" = "authors"."id" WHERE "authors"."name" = 'Karel'))
ORDER BY "posts"."id" ASC LIMIT 1
我想我一定会错过一些东西。简而言之:如何从上面的my_query之类的选择管理器(或其他选择管理器完成相同的事情)中获得活动的记录关系。
答
无法从sql字符串中获取ActiveRecord ::从Arel :: SelectManager的关系。您有两种方法通过ActiveRecord加载数据:
-
在Arel中执行所有查询逻辑。在这种情况下,您不能使用任何ActiveRecord :: Relation方法。但是你在Arel中有相同的功能。在您的例子中,你可以通过阿雷尔限量:
my_query.take(10)
-
另一种方式是在ActiveRecord的::关系的方法来使用阿雷尔。你可以重写查询是这样的:
posts = Arel::Table.new :posts authors = Arel::Table.new :authors join = posts.join(authors). on(posts[:author_id].eq(authors[:id])). join_sources my_query = Post. joins(join). where(authors[:name].eq('Karl')) > my_query.class => ActiveRecord::Relation
在这种情况下,你可以使用my_query
如的ActiveRecord ::关系