Ruby on rails 3 获取rails中作用域的补码/a筛选出匹配项的作用域

Ruby on rails 3 获取rails中作用域的补码/a筛选出匹配项的作用域,ruby-on-rails-3,scope,inverse,Ruby On Rails 3,Scope,Inverse,我正在构建一个模型来跟踪给定用户阅读的帖子(在Rails 3中)。跟踪此信息的表格是“读数”。读数同时属于:user和:post,两者都有许多:读数。当用户看到一篇文章时,它被标记为已读,并使用用户id和帖子id创建一个“正在阅读”。这似乎可以正常工作,但现在我尝试编写一个范围,只返回给定用户的未读文章。找到阅读帖子很好: scope :read, lambda { |user_id = nil | user_id.nil? ? {} : joins(:readings).

我正在构建一个模型来跟踪给定用户阅读的帖子(在Rails 3中)。跟踪此信息的表格是“读数”。读数同时属于:user和:post,两者都有许多:读数。当用户看到一篇文章时,它被标记为已读,并使用用户id和帖子id创建一个“正在阅读”。这似乎可以正常工作,但现在我尝试编写一个范围,只返回给定用户的未读文章。找到阅读帖子很好:

scope :read, lambda { |user_id = nil |       
    user_id.nil? ? {} : joins(:readings).where('readings.user_id = :user_id', :user_id => user_id)
}
然而,我试图返回此集合的补码(未读帖子)的尝试失败了。如何做到这一点?有没有一种通用的方法来编写一个只返回另一个作用域(方法)的补码(这里是:read)的作用域(方法)?我也很乐意将其作为与作用域相同的类方法编写

请记住,阅读仅在阅读帖子时创建,因此新帖子将没有阅读。这似乎比为每个新帖子的每个用户创建条目更经济

编辑:好的,我越来越接近了-下面的范围几乎可以工作,但不要求一篇文章的所有读数都不等于用户id。因此,如果用户1读过一篇文章,用户2也读过一篇文章,那么其他读数会被查询并发现不相等。所以这篇文章被错误地发现是未读的

scope :unread, lambda { |user_id = nil |       
    user_id.nil? ? {} : includes(:readings).where('(readings.user_id IS NULL OR readings.user_id != :user_id)', :user_id => user_id)
}

嗯,看起来下面的方法很有效。但仍在测试中。如果有人在这里发现一个洞,很乐意重新打开

scope :unread_by, lambda { |user_id = nil, hide_unread = nil|
      { :joins => "LEFT JOIN readings ON  readings.post_id    = post.id
          AND readings.user_id        = #{user_id}",
          :conditions => 'readings.id IS NULL' }
}