I have User
and Collection
models, and am using the Ancestry gem to support nested sub-Collections.
Each collection has many admin_users
and each user is the admin of many collections:
# user.rb
class User < ApplicationRecord
has_many :admins
has_many :collections, through: :admins
end
# collection.rb
class Collection < ApplicationRecord
has_ancestry
has_many :admins
has_many :admin_users, through: :admins, source: :user
end
# admin.rb
class Admin < ApplicationRecord
belongs_to :collection
belongs_to :user
end
Each user that is an admin of a collection should automatically be an admin of all its descendants, without having to explicitly create an Admin
record in the database for each. What's the "Rails way" to determine if a User is an admin of a collection or one of its ancestors?
I haven't used the ancestry
gem before. But as far as I understand our requirements, you need to query the path_ids
(see tree navigation) for the given collection. And then find all users that are an admin for at least one of those path items (collections from the current collection to the root collection).
I would add an instance method path_admins
to the Collection
class like this:
# in app/models/collection.rb
def path_admins
User
.distinct
.joins(:admins)
.where(admins: { collection: path_ids })
end