因此,我有一个多态的Notification模型,并且我希望能够过滤掉notifiable_typeCommentcomment.user == current_user的通知。换句话说,我想要所有通知记录-除了那些引用当前用户所作评论的记录。

class Notification

  belongs_to :notifiable, :polymorphic => true

  scope :relevant, lambda { |user_id|
    find(:all, :conditions => [
      "notifiable_type != 'Comment' OR (notifiable_type = 'Comment' AND " <<
        "comments.user_id != ?)",
      user_id ],
      :include => :comments
    )
  }

end

我不明白我需要做什么才能获得评论?我需要告诉ActiveRecord在notifiable_id上外部加入注释模型。

最佳答案

首先,不建议使用带参数的lambda范围。改用类方法:

class Notification
  belongs_to :notifiable, polymorphic: true

  def self.relevant(user_id)
    # ...
  end
end

我通常将作用域函数移到其自己的模块中,但是您可以将其保留在那里。

接下来,不赞成使用find(:all),不赞成使用:conditions。我们现在使用ActiveRelation queries

不幸的是,ActiveRecord::Relation API不够强大,无法满足您的需求,因此我们不得不使用ARel。有点棘手,但是出于安全原因,您绝对不想进行字符串替换。
class Notification
  belongs_to :notifiable, polymorphic: true

  def self.relevant(user_id)
    n, c = arel_table, Comment.arel_table
    predicate = n.join(c).on(n[:notifiable_id].eq(c[:id]))

    joins( predicate.join_sql ).
    where{ ( notifiable_type != 'Comment' ) |
      (( notifiable_type == 'Comment' ) & ( comments.user_id == my{user_id} ))
    }
  end
end

我在这里使用ARel和Squeel的组合。 Squeel非常好,应该是Rails的核心功能。我尝试编写没有Squeel的where子句,但是我很难放弃。

如果没有方便的项目就很难测试这样的东西,但是希望至少可以使您更接近。

07-27 20:22