带连接的Activerecord查询

时间:2014-06-22 14:44:43

标签: sql ruby-on-rails public-activity

到目前为止,我对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>

2 个答案:

答案 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