Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

packy's avatar
Level 7

Get "Grandparent" relationship from child

So I have been trying to figure this out for a while and I just kind find the right relationship, or am using it wrong. Basically I am trying to get the "Grandparent" relationship from the child. Right now I have 3 tables:

merchandises
-id
-product_type_id;
-name;
-description;
-slug;

product_types
-id
-shop_category_id;
-name;
-slug;

shop_categories
-id
-name;
-slug;

So on the Merchidese model I want to be able to get the shop_category slug. I thought the relationship would be

public function shopCategory()
    {
        return $this->hasOneThrough(ShopCategory::class, ProductType::class);
    }

but that assumes product_types has a merchandise_id which it doesnt.

Merchandise HasOne ProuductType that HasOne ShopCategory. So how do I get the ShopCategory from the Merchandise??

0 likes
2 replies
packy's avatar
Level 7

Never mind. I just ended-up walking up the chain. Not sure why I didnt do that in the first place?????

so to get the slug I just needed:

$this->productType->shopCategory->slug

willvincent's avatar

I have an app in production that is basically multi-tenant, users belong to organizations, and organizations exist in a hierarchy in the system. A user of any given organization can access content in their own organization and any descendants, but not content of their ancestors.. those ancestors however can of course access that organizations data as that organization is a decendant of the ancestor..

The way I modeled that in the DB so that I can quickly and painlessly find things any given user can access is that my organizations have both a parent id (the immediate parent organization) and an "ancestor tree" that is the ids of every organization higher in the hierarchy strung together with dashes..

ie:

org 1 has children 2 and 3

  • org 2 has children 4 5 6
  • org 3 has children 7 and 8
  • org 5 has children 9 and 10
  • org 9 has child 11
+ org1
  \
  + org 2
  |\
  | +-- org 4
  | +-- org 5
  | |\
  | | +--- org 9
  | | |\
  | | | +---- org 11
  | | +--- org 10
  | +-- org 6
  + org 3
   \
    +-- org 7
    +-- org 8

The db records look like this:

id     | parent_id | ancestor_tree
1      | null      | null     
2      | 1         | -1-
3      | 1         | -1-
4      | 2         | -1-2-
5      | 2         | -1-2-
6      | 1         | -1-
7      | 3         | -1-3-
8      | 3         | -1-3-
9      | 5         | -1-2-5-
10     | 5         | -1-2-5-
11     | 9         | -1-2-5-9-

So I can easily determine orgs that have content a user can access by querying where the org id is x, or the parent is x, or ancestor tree like %-x-%

It would also be trivial for any given item to look at the ancestor tree and determine it's grandparent, great grantparent, etc.

Thought I'd share because it can be considerably faster than querying several times to walk back through some relationships.

1 like

Please or to participate in this conversation.