closure_tree icon indicating copy to clipboard operation
closure_tree copied to clipboard

Could there be an option for with_ancestor to include ancestors?

Open beatgutzwiller opened this issue 2 years ago • 0 comments

I wonder why there is no way to include the ancestors in the with_ancestor scope (see code below). It is a really common use case for my project, so I started to ask myself if I am too stupid and don't see an obvious method to do that.

Let me explain a bit. For example we have a group hierarchy with managers. A manager can have multiple directly managed groups. A manager can always manage all groups below a directly managed group, but lower groups can have another manager too.

So if we have the constellation [1, 1.1, 1.1.2, 1.2] and user A is the direct manager of 1 and user B is manager of 1.1, A can manage all groups, and B can manage 1.1 and 1.1.2.

I know there are solutions. Like

Group.where(id: Group.with_ancestor(Group.where(manager: user)).select(:id)).or(Group.where(manager: user))

Which isn't to bad but a bit annoying, since the instance methods have the self_ feature (self_and_descendants vs descendants).

So my question, is there a reason, this has not been added or I am the only one needing it?

================================ Possible change to the gem:

  def self.with_ancestor(*ancestors, include_ancestors: false)
    ancestor_ids = ancestors.map { |ea| ea.is_a?(ActiveRecord::Base) ? ea._ct_id : ea }
    scope = if ancestor_ids.blank?
              all
            else
              joins(:ancestor_hierarchies)
                .where("#{_ct.hierarchy_table_name}.ancestor_id" => ancestor_ids)
                .readonly(false)
            end

    scope = scope.where("#{_ct.hierarchy_table_name}.generations > 0") unless include_ancestors
    _ct.scope_with_order(scope)
  end

beatgutzwiller avatar Apr 17 '23 08:04 beatgutzwiller