【问题标题】:In Rails, How to Eager Load an Association only if the Association is not nil?在 Rails 中,仅当关联不为零时如何急切加载关联?
【发布时间】:2013-12-20 20:14:09
【问题描述】:

我正在尝试使用 public_activity gem 创建活动日志。当我加载特定用户的活动时,我使用以下命令:

@activity = PublicActivity::Activity.order("created_at desc").where(owner_id: @awardleader.authentication.id).includes(:trackable, trackable: :awardunit)

在这里,awardunit 关联不会一直存在。由于我跟踪了多个模型,因此有时跟踪的模型没有奖励单元。那么,我们如何才能只在关联可用时才急切加载关联呢?

PS:我想获取所有活动...在该列表中,可以有来自不同模型的活动。某些模型没有 Awardunit 作为关联。因此,上面的代码给出了一个错误,指出该模型没有 Awardunit!

PS:如果我使用我在问题中显示的代码,它会给我这样的错误“在 Gold 上找不到名为 'awardunit' 的协会;也许你拼错了?”。问题是我无法删除正在加载的 Award_unit,因为一些可追踪对象有 Awardunit

【问题讨论】:

  • 您要查找所有活动,还是只查找具有可跟踪 AwardUnit 的活动?
  • @janfoeh 所有活动...在该列表中,可以有来自不同模型的活动。某些模型没有 Awardunit 作为关联。因此,上面的代码给出了一个错误,指出该模型没有 Awardunit!

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


【解决方案1】:

包括多态关联,如

PublicActivity::Activity.includes(:trackable)

会回来

  1. 所有活动,无论它们是否具有可跟踪的关联。如果没有可追踪的,则不会加载任何其他内容。
  2. 包括存在的任何类型的可追踪对象,无论其类型如何

它通过为数据库生成一个LEFT OUTER JOIN 来做到这一点。

声明一个关联是多态的,如

class PublicActivity::Activity < ActiveRecord::Base
  belongs_to :trackable, polymorphic: true
end

activities 数据库表中添加两列,trackables_typetrackables_id。您可以在查询中使用这些。

如果您只想获取具有任何种可跟踪关联的活动,请使用

PublicActivity::Activity.includes(:trackable).where.not(trackable_type: nil)

如果您只想获取与 AwardUnit 关联的活动,请使用

PublicActivity::Activity.includes(:trackable).where(trackable_type: :award_unit)

【讨论】:

  • 其实我需要它,只有当 :award_unit 可用于该模型时才急切加载 :award_unit。
  • 如果我使用我在问题中显示的代码,它会给我这样的错误“在 Gold 上找不到名为 'awardunit' 的协会;也许你拼错了?”。问题是我无法删除正在加载的 Award_unit,因为某些可追踪对象有 Awardunit
  • @EApubs 但这就是它开箱即用的功能:如果它可用,它将被包括在内 - 否则它什么也不做。您收到错误是因为 .includes(:trackable, trackable: :awardunit) 不起作用。请改用.includes(:trackable)。你不能only include trackables 如果它们是AwardUnits,你只能include 所有 trackables,不管它们的类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多