Catalog model:
has_many :categories, dependent: :destroy
has_many :docs, through: :categories
Doc model:
belongs_to :category
My goal is to obtain a collection of all Doc objects that meet my query, but only those docs that are in a catalog that the user is authorized for via Pundit.
I currently have:
catalogs = Pundit.policy_scope(user, Catalog) #get only catalogs I'm authorized for
docs = []
catalogs.each do |catalog|
catalog.docs.where(["title like ?", query]).each do |doc|
docs.push doc
end
end
This returns the records I want, but seems inefficient to me, and I would prefer to have an ActiveRecord collection rather than an array. Is there a way to obtain these records more directly? I initially tried something like:
docs = Pundit.policy_scope(user, Catalog).docs
But that didn't work. Couldn't find a method named docs
on the collection. Seems like normally you could use some kind of join for this, but I can't figure out how to make this work using Pundit to filter the catalog.
Using meagar's suggestions, I've come up with this:
category_ids = Pundit.policy_scope(user, Catalog).joins(:categories).flat_map(&:category_ids)
docs = Doc.where(category_id: category_ids).where(['title like ?', query])
Which works. Is this as efficient as I can go? Is there a more "Railsy" way to do this?