到目前为止,我对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?
,我可以看到可跟踪对象是否为nil,但我无法弄清楚如何在查询中执行此操作,即使在搜索S.O.和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>
答案 0 :(得分: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
即可。重要的是你永远不应该设计一个系统,其中外键可以指向已删除的记录。
答案 1 :(得分:0)
据我了解,您希望收到所有可跟踪的活动记录,但不会只显示tackable_id。因此,您只需joins(:trackable)
这将查询INNER JOIN
并按您希望的方式工作。此查询将仅在可能的情况下连接可跟踪和活动表(其中trackable_id存在且此id存在于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