简体   繁体   English

获取Rails中所有模型类型记录的所有相关数据?

[英]Get all associated data for all records of a model type in Rails?

How do I meld together getting all of the associated data for all of the records of a given model? 如何合并获取给定模型的所有记录的所有相关数据?

I have the following models: 我有以下型号:

User --N:1--> Reservation <--1:N-- Concert

So pseudo-code: 所以伪代码:

Reservation belongs_to User
Reservation belongs_to Concert
User has_many Reservations
User has_many Concerts through Reservations
Concert has_many Reservations
Concert has_many Users through Reservations

How do I make a single big array of everything? 如何制作一大堆所有内容?

  • I can get all my Reservations via Reservation.all 我可以通过Reservation.all获得所有Reservation.all
  • I can get the User for a particular Reservation via Reservation.find(25).user 我可以通过Reservation.find(25).user获取特定预订的用户
  • I can get the Concert for a particular Reservation via Reservation.find(25).concert 我可以通过Reservation.find(25).concert获得特定预订的音乐会

But how do I get it for all of them? 但我如何为所有人获得它呢? If I do 如果我做

Reservation.all.each do |res|
   res.user.name+","+res.concert.name+","+res.concert.date # etc.
end

Then it will do two new database queries for each reservation as it loops through. 然后,当它循环时,它将为每个预留执行两个新的数据库查询。 For 10 records, it might not matter, but for thousands, it can be very painful. 对于10条记录,它可能无关紧要,但对于数千条记录来说,它可能会非常痛苦。 Add to it other associations (eg Concert belongs_to venue, User has_one email, etc.)... 添加其他关联(例如Concert belongs_to场地,User has_one email等)......

Is there any way to say, "Get all of the reservations and the following attached info" so it loads in a single SQL query? 有没有办法说,“获取所有预订和以下附加信息”,以便它加载到一个SQL查询?

What you're trying to accomplish is called eager loading , and can be done using includes in ActiveRecord . 您要完成的任务称为急切加载 ,可以使用ActiveRecord includes来完成。 See below: 见下文:

N + 1 queries problem N + 1查询问题

Active Record lets you specify in advance all the associations that are going to be loaded. Active Record允许您事先指定要加载的所有关联。 This is possible by specifying the includes method of the Model.find call. 这可以通过指定Model.find调用的includes方法来实现。 With includes, Active Record ensures that all of the specified associations are loaded using the minimum possible number of queries. 使用includes,Active Record可确保使用尽可能少的查询加载所有指定的关联。

http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations

In your example you could use the following: 在您的示例中,您可以使用以下内容:

Reservation.all.includes(:user, :concert)

It is also a good idea to specify the :inverse_of option for your :belongs_to relations. :belongs_to关系指定:inverse_of选项也是一个好主意。 This optimizes object loading and makes sure that cross-referencing a model will point back to the same object in memory, ie: 这样可以优化对象加载并确保交叉引用模型将指向内存中的同一对象,即:

@user == @user.reservations.first.user # true

More information available here: 更多信息请点击此处:

If you are using a belongs_to on the join model, it is a good idea to set the :inverse_of option on the belongs_to ... 如果您在连接模型上使用belongs_to,最好在belongs_to上设置:inverse_of选项...

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

In your example: 在你的例子中:

# app/models/reservation.rb

belongs_to :user, :inverse_of => :reservations
belongs_to :concert, :inverse_of => :reservations

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM