[英]Ruby on Rails / ActiveRecord: How Can I (Elegantly) Retrieve Data from Multiple Tables?
It's rather trivial to retrieve data from multiple tables that are related through foreign keys using raw SQL.使用原始 SQL 从通过外键关联的多个表中检索数据相当简单。 I can do, for example:
我可以这样做,例如:
SELECT title, domestic_sales
FROM movies
JOIN boxoffice
ON movies.id = boxoffice.movie_id;
This would give me a table with two colums: title
and domestic_sales
, where the data in the first column comes from the table movies
and the data in the second column comes from the table boxoffice
.这将给我一个包含两列的表:
title
和domestic_sales
销售,其中第一列中的数据来自表movies
,第二列中的数据来自表boxoffice
。
How can I do this in Rails using Ruby code?如何使用 Ruby 代码在 Rails 中执行此操作? I can, of course, get the same result if I use raw SQL.
当然,如果我使用原始 SQL,我可以获得相同的结果。 So, I could do the following:
因此,我可以执行以下操作:
ActiveRecord::Base.connection.execute(<<-SQL)
SELECT title, domestic_sales
FROM movies
JOIN boxoffice
ON movies.id = boxoffice.movie_id;
SQL
This would give me a PG::Result
object with the data I want.这会给我一个
PG::Result
object 和我想要的数据。 But this is super inelegant.但这是超级不雅的。 I would like to be able to get this information without using raw SQL.
我希望能够在不使用原始 SQL 的情况下获取此信息。
So, this is the first thing that comes to mind is:所以,首先想到的是:
Movie.select(:name, :domestic_sales).joins(:box_office)
The problem, however, is that the aforementioned line of code returns a bunch of Movie
objects.然而,问题在于上述代码行返回了一堆
Movie
对象。 Since the Movie
class doesn't have the domestic_sales
attribute, I don't get access to that information.由于
Movie
class 没有domestic_sales
销售属性,我无法访问该信息。
The next thing I thought was to use a loop.接下来我想到的是使用循环。 So, I could do something like:
所以,我可以做类似的事情:
Movie.joins(:box_office).to_a.map do |m|
{name: m.name, rating: m.box_office.domestic_sales}
end
This gives me exactly the data I want.这给了我我想要的数据。 But it costs n + 1 SQL queries, which is not good.
但是它花费 n + 1 SQL 查询,这不好。 I should be able to get this with just one query...
我应该能够通过一个查询得到这个......
So: How can I retrieve the data I want without using raw SQL and without using loops that cost multiple queries?那么:如何在不使用原始 SQL 并且不使用需要多次查询的循环的情况下检索我想要的数据?
SELECT title, domestic_sales
FROM movies
JOIN boxoffice
ON movies.id = boxoffice.movie_id;
translated to ActiveRecord
would look like this翻译成
ActiveRecord
看起来像这样
Movie
.select(:title, :domestice_sales)
.joins("boxoffice ON movies.id = boxoffice.movie_id")
When you have proper associations defined in your models you would would be able to write:当您在模型中定义了适当的关联时,您将能够编写:
Movie
.select(:title, :domestice_sales)
.joins(:boxoffices)
And when you do not need an instance of ActiveRecord
and would be fine with a nested array, you can even write:当您不需要
ActiveRecord
的实例并且可以使用嵌套数组时,您甚至可以编写:
Movie
.joins(:boxoffices)
.pluck(:title, :domestice_sales)
Try this way.试试这个方法。
Movie.joins(:box_office).pluck(:title, :domestic_sales)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.