如何在不加载关联模型的情况下检查 has_one 是否存在
how to check if has_one exists without loading associated model
我有一个简单的has_one关系
class User < ApplicationRecord
has_one :detail
has_many :courses
end
class Detail < ApplicationRecord
belongs_to :user
end
我需要检查用户是否有详细信息。既然我可以做到 User.first.courses.exists?
,令人惊讶的是 User.first.detail.exists?
不起作用。我可以 !User.first.detail.nil?
但我只需要检查用户详细信息是否存在而不加载它非常庞大的细节模型。
在不检索整个关联模型的情况下检查 has_one 关联是否存在的好方法是什么?
您可以使用:User.first.detail.present?
Detail.where(user_id: User.first.id).exists?
如果您只想知道用户是否有详细信息,那么这不会分配 Detail
对象。
要在不访问数据库的情况下检查关联是否已加载,您可以使用:
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
预加载
预加载让您提前加载数据,因此关联被标记为已加载:
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!)
这是因为当您执行 .first
以提高效率时,它实际上是在执行 SELECT * LIMIT 1
查询。
预加载
user = User.eager_load(:courses).find(1)
user.association(:courses).loaded? # => true
什么时候使用 loaded?
方法?
我能想到的唯一用例是当您不想触发数据库调用但想检查数据是否已经加载并且仅在加载时才对其进行处理。
在我的例子中,我想输出一些数据用于记录目的,但前提是它没有通过调用关联添加额外的数据库查询。
我有一个简单的has_one关系
class User < ApplicationRecord
has_one :detail
has_many :courses
end
class Detail < ApplicationRecord
belongs_to :user
end
我需要检查用户是否有详细信息。既然我可以做到 User.first.courses.exists?
,令人惊讶的是 User.first.detail.exists?
不起作用。我可以 !User.first.detail.nil?
但我只需要检查用户详细信息是否存在而不加载它非常庞大的细节模型。
在不检索整个关联模型的情况下检查 has_one 关联是否存在的好方法是什么?
您可以使用:User.first.detail.present?
Detail.where(user_id: User.first.id).exists?
如果您只想知道用户是否有详细信息,那么这不会分配 Detail
对象。
要在不访问数据库的情况下检查关联是否已加载,您可以使用:
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
预加载
预加载让您提前加载数据,因此关联被标记为已加载:
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!)
这是因为当您执行 .first
以提高效率时,它实际上是在执行 SELECT * LIMIT 1
查询。
预加载
user = User.eager_load(:courses).find(1)
user.association(:courses).loaded? # => true
什么时候使用 loaded?
方法?
我能想到的唯一用例是当您不想触发数据库调用但想检查数据是否已经加载并且仅在加载时才对其进行处理。
在我的例子中,我想输出一些数据用于记录目的,但前提是它没有通过调用关联添加额外的数据库查询。