我正在尝试使用带有关系的查询。
在这种情况下,如何查询在哪里使用关系?
这是模特
User
has_many :projects
has_many :reasons, through: :projects
Project
belongs_to :user
has_many :reasons
Reasons
belongs_to :project
这是无效的代码
# GET /reasons
def index
reasons = current_user.reasons
updated_at = params[:updated_at]
# Filter with updated_at for reloading from mobile app
if updated_at.present?
# This one doesn't work!!!!!!!!!!!!
reasons = reasons.includes(:projects).where("updated_at > ?", Time.at(updated_at.to_i))
# Get all non deleted objects when logging in from mobile app
else
reasons = reasons.where(deleted: false)
end
render json: reasons
end
- -更新 - -
感谢@AmitA,这是正确的。
reasons = reasons.joins(:project).where("projects.updated_at > ?", Time.at(updated_at.to_i))
如果要查询项目受某些约束的所有原因,则需要使用joins
代替includes
:
reasons = reasons.joins(:project).where("projects.updated_at > ?", Time.at(updated_at.to_i))
需要注意的是当两个includes
和joins
接收他们寻找一个符号协会与准确名称。这就是为什么您实际上不能做includes(:projects)
,但必须做includes(:project)
或做的原因joins(:project)
。
还要注意,对所指定的联接表的约束where
必须引用表名,而不是关联名。这就是为什么我使用projects.updated_at
(以复数形式)而不是其他任何形式的原因。换句话说,调用该where
方法时,您位于“ SQL域”中。
includes
和之间有区别joins
。includes
运行一个单独的查询以加载相关项,然后将其填充到获取的活动记录对象中。所以:
reasons = Reason.where('id IN (1, 2, 3)').includes(:project)
将执行以下操作:
SELECT * FROM reasons WHERE id IN (1,2,3)
,并Reason
为每个记录构造ActiveRecord对象。SELECT * FROM projects WHERE id IN (11,12,13)
并Project
为每个记录构造ActiveRecord对象。project
的每个Reason
ActiveRecord对象的关联。上面的最后一步意味着您可以安全地执行以下操作:
reasons.first.project
并且不会启动查询来获取第一个原因的项目。这就是为什么includes
用于解决N + 1个查询的原因。但是,请注意,SQL中没有JOIN子句发生-它们是单独的SQL。因此,使用时不能添加SQL约束includes
。
就是这样joins
。它只是连接表,以便您可以where
在连接的表上添加约束。但是,它不会为您预先填充关联。实际上,Reason.joins(:project)
永远不会实例化Project
ActiveRecord对象。
如果要同时执行“joins
和”操作includes
,则可以使用第三个方法eager_load
。您可以在此处阅读更多有关差异的信息。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句