Rails querying an associated models scope

对着背影说爱祢 提交于 2021-02-10 06:39:06

问题


I am struggling to find a suitable solution for what should be a simple task. Essentially I have a category model which has many posts. The post belongs to the category.

I am displaying categories as part of a search form as well as a number of other places and do not want to display categories that have no associated posts. That seems kind of pointless.

I managed to solve this problem by adding the following method to my category model.

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

That works fine allowing me to filter categories that have no results. The slightly more confusing bit is when I try to use scopes.

My Post has several scopes such as frontend_visible which dictates whether it should be accessible from the frontend (non-admin).

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

Equally I have other scopes to pull posts that are marked as private content only (members only).

The problem with my initial solution is that a category that contains posts which are not approved will not be shown, equally non-members will not be able to see posts that are marked as private although the category will still be shown.

The ideal solution would be something like:

Get all categories that have associated posts, if associated posts are not frontend visible, disregard category. If current_user can not access private content and all associated posts are marked private, disregard category.

I have the scopes but I am unsure how to use them from the associated model. Is this possible?


回答1:


As i understand, you need to select categories with posts visible to an user. For that you need to do two things:

  1. Make mapping between user’s roles and post’s visible scopes
  2. Select categories for posts visible by user. In your case it’s easier to select that categories in two queries, without joins.

Try this code:

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


来源:https://stackoverflow.com/questions/43209400/rails-querying-an-associated-models-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!