要检查关联是否已加载而不点击数据库,您可以使用:
model.association(:association_name).loaded? 用于has_one/belongs_to 关联,model.many_things.loaded? 用于has_many 关联。
检查 has_one/belongs_to 关联是否已加载:
user = User.find(1)
user.association(:detail).loaded? # => false
user.detail.id # Does DB request to get Detail
user.association(:detail).loaded? # => true
预加载
Eager loading 让您可以提前加载数据,因此正如预期的那样,关联被标记为已加载:
user = User.eager_load(:detail).find(1)
user.detail.loaded? # => true
检查 has_many 关联是否已加载
使用 has_many 关联,
user = User.find(1)
user.association(:courses).loaded? # => false
user.courses.load # Does DB query to get all users' courses
user.association(:courses).loaded? # => true
执行.first 或其他一些查询不会总是加载
请记住,它并非在所有情况下都标记为已加载:
user.courses.first.id # Does DB query to get first course ID
user.association(:courses).loaded? # => false (still!)
这是因为它实际上是在执行 SELECT * LIMIT 1 查询时,您为了提高效率而执行 .first。
预加载
user = User.eager_load(:courses).find(1)
user.association(:courses).loaded? # => true
何时使用loaded? 方法?
我能想到的唯一用例是当您不想触发数据库调用但您想检查数据是否已经加载并仅在加载时才对其进行处理。
在我的例子中,我想输出一些数据用于记录目的,但前提是它没有通过调用关联添加额外的数据库查询。