Rails 查询关联的模型范围

Posted

技术标签:

【中文标题】Rails 查询关联的模型范围【英文标题】:Rails querying an associated models scope 【发布时间】:2017-08-29 18:45:48 【问题描述】:

我正在努力寻找适合本应简单任务的解决方案。基本上我有一个类别模型,它有很多 帖子帖子属于类别

我正在将类别显示为搜索表单以及许多其他地方的一部分,并且不想显示没有关联帖子的类别。这似乎有点毫无意义。

我设法通过将以下方法添加到我的 category 模型来解决此问题。

# Check if Category has associated results
def self.with_results
  includes(:posts).where.not(posts:  id: nil )
end

这很好,让我可以过滤没有结果的类别。更令人困惑的是当我尝试使用作用域时。

我的帖子有几个范围,例如frontend_visible,它指示是否应该从前端(非管理员)访问它。

scope :frontend_visible, ->  where(:state => ['approved', 'changes_pending_approval']) 

同样,我还有其他范围来提取标记为仅限私人内容的帖子(仅限会员)。

我最初解决方案的问题是不会显示包含未批准帖子的类别,同样非会员将无法看到标记为私人的帖子,尽管该类别仍将显示。

理想的解决方案是这样的:

获取所有有关联帖子的类别,如果关联帖子在前端不可见,则忽略类别。如果 current_user 无法访问私有内容并且所有相关帖子都标记为私有,则忽略类别。

我有范围,但我不确定如何从相关模型中使用它们。这可能吗?

【问题讨论】:

所以您希望所有类别的帖子都在前端可见? Category.includes(:posts).where(frontend_visible: true).where.not(posts: id: nil) ... 如果您使用的是 Rails5,则不需要加载关联的表只是查询它是否有关联的记录: Category.where(frontend_visible: true).left_outer_joins(:posts).where(posts: id: nil ) here 您可以找到解决方案...例如合并范围或范围范围... @bkunzi01 谢谢你,但是你的例子都不适合我。我收到以下错误:PG::UndefinedColumn: ERROR: column categories.frontend_visible 不存在 @rfellons 谢谢。我之前确实看过该指南。我想我正在努力使用范围作为关联模型中的条件。我找不到这种用法的明确示例 只要花点时间学习主动记录。这不是一个困难的概念,所以如果您阅读文档,您可以轻松地进行任何您需要的查询。 【参考方案1】:

据我了解,您需要选择帖子对用户可见的类别。为此,您需要做两件事:

    在用户的角色和帖子的可见范围之间建立映射 为用户可见的帖子选择类别。在您的情况下,在两个查询中选择这些类别会更容易,无需连接。

试试这个代码:

class Category < ApplicationRecord
  has_many :posts

  scope :with_posts_for_user, -> (user) do
    where(id: Post.categories_for_user(user))
  end
end

class Post < ApplicationRecord
  belongs_to :category

  scope :frontend_visible, ->  where(:state => ['approved', 'changes_pending_approval']) 
  scope :member_visible, ->  where(:state => ['approved', 'changes_pending_approval', 'private']) 

  scope :categories_for_user, -> (user) do
    (user.member? ? member_visible : frontend_visible).distinct.pluck(:category_id)
  end
end

【讨论】:

您的解决方案非常好,感谢您抽出宝贵时间分享!

以上是关于Rails 查询关联的模型范围的主要内容,如果未能解决你的问题,请参考以下文章

由关联计数组成的 Rails 查询,最好使用范围

rails 范围检查关联是不是不存在

带有关联的 Rails 范围

Rails - has_one 关系:关联和非关联对象的范围

如何将参数传递给 Rails 4 中的 has_many 关联范围?

与Ruby on Rails中的范围相关联