0

到目前为止,我对 gem PublicActivity有这个查询。它的一个(我知道的)问题是,如果 activity.trackable 为 nil,它仍会将其包含在查询中,从而迫使我在视图中运行条件,if activity.trackable如果可跟踪对象,这基本上会有所帮助已被删除,因此您不要尝试访问 nil 对象。

PublicActivity::Activity.
  includes(:trackable, :owner).
  order('created_at DESC').
  where(recipient_id: current_user, kind: "Notification", read: false).
  where('owner_id not in (?)', current_user).
  size

我想包含一个where查询以仅查询activity.trackable IS NOT NULL. 在视图中,使用:activity.trackable.nil?,我可以查看可跟踪对象是否为零,但我无法弄清楚如何在查询中执行此操作,即使在搜索 SO 和 rails api/docs 之后也是如此。任何指导将不胜感激。

编辑

即使在您销毁trackable对象后,trackable_id仍将存储在activity. 下面是我销毁对象的活动示例。trackable

#<PublicActivity::Activity id: 389, trackable_id: 865, trackable_type: "Vote", owner_id: nil, owner_type: nil, key: "vote.update", parameters: {}, recipient_id: nil, recipient_type: nil, created_at: "2014-06-22 14:33:37", updated_at: "2014-06-22 14:33:37", kind: nil, read: false>
4

2 回答 2

1

在. where('activities.trackable_id is not null')_ .size如果您的表是命名空间的,您可能需要使用'public_activity_activities.trackable_id is not null'

如果trackable_id指向不再存在的记录,您将遇到更大的问题。解决方案是修复该错误,而不是解决它。要么添加一个外键约束,将trackable_id关联null记录设置为何时删除,或者修复你的 Rails 关联,以使用一个选项将字段设置null为关联对象被销毁的时间。:dependent

生成的关联看起来像这样:

class Trackable < ActiveRecord::Base
  has_one :activity, dependent: :nullify
end

不要忽视这一点,也不要设计一个以这种方式工作的系统。有悬空的外键是非常严重的数据不一致;您实际上破坏了关系数据库的全部目的。

或者,实际上不要破坏您的对象。使用“软删除”策略,您只需将active字段切换为false. 重要的是,您永远不应该设计一个可能让外键指向已删除记录的系统。

于 2014-06-22T14:59:44.950 回答
0

据我了解,您希望接收所有可跟踪的活动记录,但不是仅存在 tackable_id 的地方。因此,您可以简单地joins(:trackable)查询INNER JOIN并按照您想要的方式工作。此查询将仅在可能的情况下(trackable_id 存在且此 id 存在于 trackables 表中)连接 trackables 和活动表。

PublicActivity::Activity.
   includes(:trackable, :owner).
   joins(:trackable).
   order('created_at DESC').
   where(recipient_id: current_user, kind: "Notification", read: false).
   where('owner_id not in (?)', current_user).
   size
于 2014-06-22T16:39:39.610 回答