MST

星途 面试题库

面试题:Ruby on Rails 框架中的 ActiveRecord 关联优化

假设你有两个模型 `Author` 和 `Book`,一个作者可以写多本书,一本书属于一个作者。请阐述如何使用 ActiveRecord 关联来表示这种关系,并且说明在查询操作中,如何使用 `includes` 和 `joins` 方法优化查询性能,避免 N + 1 问题。
13.0万 热度难度
编程语言Ruby

知识考点

AI 面试

面试题答案

一键面试
  1. ActiveRecord 关联表示关系
    • Author 模型中,添加如下关联:
    class Author < ApplicationRecord
      has_many :books
    end
    
    • Book 模型中,添加如下关联:
    class Book < ApplicationRecord
      belongs_to :author
    end
    
  2. 使用 includesjoins 优化查询性能避免 N + 1 问题
    • includes 方法
      • includes 方法会使用 LEFT OUTER JOIN 进行预加载。例如,当我们想获取所有作者及其所写的书时:
      authors = Author.includes(:books).all
      authors.each do |author|
        author.books.each do |book|
          # 处理每本书
        end
      end
      
      • 这里 includes 方法会预加载所有作者及其相关的书,避免了为每个作者单独查询书的 N + 1 问题。
    • joins 方法
      • joins 方法使用 INNER JOIN。例如,当我们只想获取有书的作者时:
      authors_with_books = Author.joins(:books).distinct
      authors_with_books.each do |author|
        # 处理有书的作者
      end
      
      • joins 方法将 AuthorBook 表进行内连接,只返回有书的作者,也能在一定程度上优化查询性能,并且避免重复记录。同时结合 distinct 可以确保每个作者只出现一次。

总结来说,includes 适合获取主模型及其关联模型,即使关联模型可能为空;joins 适合获取满足关联条件的主模型记录。