How do you create a tree strucutre with ActiveRecord


#1

I want to build an application that has the concept of administrative
domains. What I mean by this is that administrators have access to
different data, based on what domains they are a member of. The domain
strucutre is hierarchical. Here is an example:

  • MLB
    • AL
      • East
        • Yankees
        • Red Sox
      • Central
      • West
    • NL
      • East
      • Central
      • West

Now image I could put users at any level of the domain, possibly even at
multple levels. If the user has administrative privleges, the user
would be
able to edit the user accounts for other users in there domain, but not
users in other domains. So, Derek Jeter would be a user in the Yankees
domain, George Steinbrenner and admin user in the Yankees domain, David
Ortiz a user in the Red Sox domain, and Bud Selig an admin user in the
MLB
domain. Since Ortiz and Jeter are just non-admin users, they can’t edit
any
other user accounts. Since steinbrenner is ad admin user in the Yankees
domain, he can edit Jeter’s account, but not Ortiz’s, because Ortiz is
not
in Steinbrenner’s domain. Bud Selig could edit both Jeter and Ortiz’s
account, because they are in sub-domains of his domain.

The database structure would have to look something like this:

Table: Domains
±—±----------±--------+
| id | parent_id | name |
±—±----------±--------+
| 1 | NULL | MLB |
| 2 | 1 | AL |
| 3 | 2 | East |
| 4 | 3 | Yankees |
| 5 | 3 | Red Sox |
±—±----------±--------+

parent_id is a FK to another domain id. A NULL parent_id indicates it
is a
top-level domain. So there would be a users and a domain_users table,
and
Domain model object would have a has_many_and_belongs_to_many
relationship
with users. But the problem is that would only allow me to query what
users
are directly in a given domain. In order to determine what users are in
a
given domain, you have to include the child domains has well. So what
users
are in domain MLB? The query would be:

SELECT * from domain_users where domain_id IN (1,2,3,4,5)

Then for steinbrenner it would be:

SELECT * from domain_users where domain_id IN (3)

But how do you write a query to know what child, grandchild, etc domains
to
use?


#2

Hi the easiest way is …drum roll …

acts_as_tree:

http://api.rubyonrails.com/classes/ActiveRecord/Acts/Tree/ClassMethods.html

hope that helps.
Mark

On 1/11/06, Paul B. removed_email_address@domain.invalid wrote:

   ...

users in other domains. So, Derek Jeter would be a user in the Yankees
Table: Domains
parent_id is a FK to another domain id. A NULL parent_id indicates it is a

Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


#3

Sounds like you are looking for ‘acts_as_tree’

Basically you define a model table like this…

id parent_id other_stuff models_count


then in your model

class Model < AR::Base
acts_as_tree :order=>“other_stuff”, :counter_cache=>true
end

then you can do all sorts of fun stuff like

model.children
model.parents
model.ancestors
model.siblings

The counter cache will keep the ‘models_count’ column up to date with
the number of children, so you only need one query for that information.

_Kevin


#4

acts_as_tree in ActiveRecord works very well for me

read “Agile Web D. in Rails” for more information


#5

Actually, the biggest problem you have is that you listed the Yankees
ahead
of the Red Sox. :slight_smile:

Ken

Kenneth A. Kousen, Ph.D.

President

Kousen IT, Inc.

http://www.kousenit.com http://www.kousenit.com

mailto:removed_email_address@domain.invalid removed_email_address@domain.invalid


From: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Paul B.
Sent: Thursday, January 12, 2006 1:14 AM
To: removed_email_address@domain.invalid
Subject: [Rails] How do you create a tree strucutre with ActiveRecord

I want to build an application that has the concept of administrative
domains. What I mean by this is that administrators have access to
different data, based on what domains they are a member of. The domain
strucutre is hierarchical. Here is an example:

  • MLB
    • AL
      • East
        • Yankees
        • Red Sox
      • Central
      • West
    • NL
      • East
      • Central
      • West

Now image I could put users at any level of the domain, possibly even at
multple levels. If the user has administrative privleges, the user
would be
able to edit the user accounts for other users in there domain, but not
users in other domains. So, Derek Jeter would be a user in the Yankees
domain, George Steinbrenner and admin user in the Yankees domain, David
Ortiz a user in the Red Sox domain, and Bud Selig an admin user in the
MLB
domain. Since Ortiz and Jeter are just non-admin users, they can’t edit
any
other user accounts. Since steinbrenner is ad admin user in the Yankees
domain, he can edit Jeter’s account, but not Ortiz’s, because Ortiz is
not
in Steinbrenner’s domain. Bud Selig could edit both Jeter and Ortiz’s
account, because they are in sub-domains of his domain.

The database structure would have to look something like this:

Table: Domains
±—±----------±--------+
| id | parent_id | name |
±—±----------±--------+
| 1 | NULL | MLB |
| 2 | 1 | AL |
| 3 | 2 | East |
| 4 | 3 | Yankees |
| 5 | 3 | Red Sox |
±—±----------±--------+

parent_id is a FK to another domain id. A NULL parent_id indicates it
is a
top-level domain. So there would be a users and a domain_users table,
and
Domain model object would have a has_many_and_belongs_to_many
relationship
with users. But the problem is that would only allow me to query what
users
are directly in a given domain. In order to determine what users are in
a
given domain, you have to include the child domains has well. So what
users
are in domain MLB? The query would be:

SELECT * from domain_users where domain_id IN (1,2,3,4,5)

Then for steinbrenner it would be:

SELECT * from domain_users where domain_id IN (3)

But how do you write a query to know what child, grandchild, etc domains
to
use?