【问题标题】:Get all associated data for all records of a model type in Rails?获取 Rails 中模型类型的所有记录的所有关联数据?
【发布时间】:2015-04-26 07:44:23
【问题描述】:

如何将给定模型的所有记录的所有关联数据融合在一起?

我有以下型号:

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 地点、用户 has_one 电子邮件等)...

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

【问题讨论】:

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


    【解决方案1】:

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

    N + 1 个查询问题

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

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

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

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

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

    @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
    

    【讨论】:

    • 啊!我在其他 ORM 中使用过预加载,并且知道 Rails 有预加载,但我不知道我可以在每个请求的基础上使用它!因此,如果我执行Reservation.all.includes(:user, :concert),它将执行 SELECT 并让所有这些都加入?
    • @deitch:是的。您可以在控制台中尝试一下,并比较两者之间正在执行的 SQL。
    • 哈!这正是我所做的。谢谢,德伦米。帮我省了很多麻烦!
    猜你喜欢
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2015-04-08
    • 1970-01-01
    相关资源
    最近更新 更多