让我说我有这段代码:
new_and_updated = Post.where(:published_at => nil).union(Post.where(:draft => true))
post = Post.arel_table
Post.from(post.create_table_alias(new_and_updated, :posts))
我从关于arel的帖子中获得了这段代码,但并没有真正解释create_table_alias
的作用。只有最后结果是活动的activeRecord::Relation
对象,这是先前定义的并集的结果。为什么需要传递:posts
作为create_table_alias
的第二个参数,这是数据库中表的名称吗?
答案 0 :(得分:2)
Arel
基本上如下
alias = Arel::Table.new(table_name)
table = Arel::Nodes::As.new(table_definition,alias)
这将为新表定义创建一个SQL别名,以便我们可以在查询中引用它。
TL; DR
让我们根据您发布的代码来解释它的工作原理。
new_and_updated= Post.where(:published_at => nil).union(Post.where(:draft => true))
此语句可以转换为以下SQL
SELECT
posts.*
FROM
posts
WHERE
posts.published_at IS NULL
UNION
SELECT
posts.*
FROM
posts
WHERE
posts.draft = 1
这是一个很好的查询,但是如果没有语法错误,则不能从中选择它作为子查询。这是别名的来源,因此此行(如上针对Arel
所述)
post.create_table_alias(new_and_updated, :posts)
成为
(SELECT
posts.*
FROM
posts
WHERE
posts.published_at IS NULL
UNION
SELECT
posts.*
FROM
posts
WHERE
posts.draft = 1) AS posts -- This is the alias
现在包装Post.from
可以从该子查询中选择,使得最终查询为
SELECT
posts.*
FROM
(SELECT
posts.*
FROM
posts
WHERE
posts.published_at IS NULL
UNION
SELECT
posts.*
FROM
posts
WHERE
posts.draft = 1) AS posts
顺便说一句,如果您使用的是Rails 5,则可以简化您的查询,这也消除了对其余代码的需求,例如
Post.where(:published_at => nil).or(Post.where(:draft => true))
将成为
SELECT
posts.*
FROM
posts
WHERE
posts.published_at IS NULL OR posts.draft = 1
答案 1 :(得分:0)
从Rails官方文档中,SWITCH(SelectedMetric,
"Sales", FORMAT([sales], "Currency"),
"Units", FORMAT([units], "0"),
"Margin", FORMAT([margin], "0.00%")
)
查询方法可以做到这一点:
指定要从中获取记录的表。
因此,为了从from
关系中获取帖子,我们需要有一个new_and_updated
正在使用的别名表。
Rubydoc for Arel's post.create_table_alias(new_and_updated, :posts)
方法告诉我们实例方法包含在create_table_alias
模块中。
此处Table
用于指定要创建的别名表的名称,而:posts
提供ActiveRecord :: Relation对象。
希望有帮助。