如何将两个范围与OR组合在一起

我有一个标签供稿和一个好友供稿。 我想结合这两个并构建最终的“全部”饲料。

对于朋友饲料:

class Post < ActiveRecord::Base
  scope :friendfeed, lambda{|x| followed_by}

  def self.followed_by(user)
    where("user_id IN (?) OR user_id = ?", user.watched_ids, user.id)
  end
end

对于标记Feed:

class Post < ActiveRecord::Base
  scope :tagfeed, lambda{|x| infatuated_with}

  def self.infatuated_with(user)
    joins(:attachments).where("attachments.tag_id IN (?)", user.tags).select("DISTINCT pages.*")
  end
end

我会从控制器中调用这样的东西(我使用Kaminari宝石作为分页):

@tag_feed = Post.tagfeed(current_user).page(params[:page]).per(21)
@friend_feed = Post.friendfeed(current_user).page(params[:page]).per(21)

现在我想拥有一个通用饲料,但我迷路了。范围是为了缩小范围,但在这种情况下,我试图执行OR操作。做类似的东西

@mother_of_all_feed = @tag_feed + @friend_feed

将是多余的,我无法控制在单个页面上显示的帖子数量。我怎么能这样做呢?谢谢!

顺便说一下,对于标签,我建立了这样的关联:

class Post < ActiveRecord::Base
  has_many :attachments
  has_many :tags, :through => :attachments
end

class Tag < ActiveRecord::Base
  has_many :attachments
  has_many :posts, :through => :attachments
end

class Attachment < ActiveRecord::Base
  belongs_to :tag
  belongs_to :post
end
0
额外 编辑
意见: 1

2 答案

这项功能有一个导轨拉取请求( https://github.com/rails/rails/pull/ 9052 ),但在此期间,有人创建了一个猴子补丁,您可以在初始化程序中包含这个补丁程序,它允许您在一个查询中使用或范围和where子句,并仍然为您提供 ActiveRecord ::关系</代码>:

https://gist.github.com/j-mcnally/250eaefef234dd8971b

有了这个,你可以像这样操作你的示波器

Post.tagfeed(current_user).or.friendfeed(current_user)

或者写一个新的范围

scope :mother_of_all_feed, lambda{|user| tagfeed(user).or.friendfeed(user)}
0
额外
凡是低估了这一点的人都会受到一些建设性的批评。它解决了这个问题,并且不会生成嵌套查询。
额外 作者 keithepley,
OR将被添加到Rails 5.0中: github.com/rails/rails/pull/16052
额外 作者 denis.peplin,
是的, OR 已被添加到Rails 5中的 ActiveRecord :: Relation#或 - nithinbekal.com/posts/rails-5-features
额外 作者 leviathan,

回答我自己的问题。我想我想出了一个办法。

where("pages.id IN (?) OR pages.id IN (?)",
  Page.where(
      "user_id IN (?) OR user_id = ?",
      user.watched_ids, user.id
  ),
  Page
    .joins(:attachments)
    .where("attachments.tag_id IN (?)", user.tags)
    .select("DISTINCT pages.*")
)

它似乎到目前为止工作,希望这是它!

0
额外
不满意,但我只是原型,所以没关系。我会看看squeel。谢谢!
额外 作者 Vlad,
你对它的表现满意吗?看起来你在这里得到4-5个查询。看起来你有两个选择:编写原始的SQL查询或使用我最喜欢的gem squeel。它允许执行OR并支持导致嵌套SQL查询的功能。看一看: github.com/ernie/squeel 。我尝试了几次“宣传”,如下所示: stackoverflow.com/a/10551561/1322562 ,但只有少数人们喜欢它。我想知道为什么。使用squeel,您可以重用您的范围并在纯Ruby中构建复杂的查询,如: Product.where {(id.in Product.ruby)|(id.in Product.rails)} !!)SQL查询!
额外 作者 jdoe,