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

时间:2015-04-26 07:44:23

标签: ruby-on-rails ruby-on-rails-4

如何合并获取给定模型的所有记录的所有相关数据?

我有以下型号:

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

所以伪代码:

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

如何制作一大堆所有内容?

  • 我可以通过Reservation.all
  • 获取所有预订
  • 我可以通过Reservation.find(25).user
  • 获取特定预订的用户
  • 我可以通过Reservation.find(25).concert
  • 获取特定预订的音乐会

但是如何为所有人获得它呢?如果我做

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

然后,当它循环时,它将为每个预留执行两个新的数据库查询。对于10条记录,它可能无关紧要,但对于数千条记录来说,它可能会非常痛苦。添加其他关联(例如Concert belongs_to场地,User has_one email等)......

有没有办法说,“获取所有预订和以下附加信息”,以便在单个SQL查询中加载?

1 个答案:

答案 0 :(得分:3)

您尝试完成的操作称为预先加载,可以使用includes中的ActiveRecord完成。见下文:

  

N + 1查询问题

     

Active Record允许您事先指定要加载的所有关联。这可以通过指定Model.find调用的includes方法来实现。使用includes,Active Record可确保使用尽可能少的查询加载所有指定的关联。

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

在您的示例中,您可以使用以下内容:

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

:inverse_of关系指定:belongs_to选项也是一个好主意。这样可以优化对象加载,并确保交叉引用模型将指向内存中的同一对象,即:

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

此处提供更多信息:

  

如果您在联接模型上使用belongs_to,最好在belongs_to上设置:inverse_of选项...

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

在你的例子中:

# app/models/reservation.rb

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