1

Consider the following scenario in Laravel 4.1

  • there is a Set model that may have many items (sorted by precedence, but this can be put aside for now)
  • each of these items can be of a different "kind" (think of a bag (the Set) that contains keys,wallet,cigs...)

Ideally I would like to achieve the following:

  • have a simplified, eager-loadable relationship between a Set and its items (explained better below)
  • keep the item models DRY (ideally each item extends an abstract class with basic boilerplate code)

To better illustrate what I have in mind:

class Set extends Eloquent {
    // ...
    public function items() {
         // provides a "transparent" method to access ALL of its items ... no matter what class
    }
}

and

class SubItemOne extends Item { // ... } 
class SubItemTwo extends Item { // ... } 

abstract class Item extends Eloquent {
    public function set() {
        return $this->belongsTo('Set');
    }
}

because at its core each sub-class shares a lot in common with the others (think of: they can all be moved around in the set, or they can be attached an image etc. ... all of which could be defined within the abstract Item class).

Essentially, I want to be able to access all of the items belonging to my Set in situations like

 Set::with('items')->find(1);

but I'm really unsure about what kind of relationship to use for the 'inverse'.

Things I've considered so far:

  • take out the subclassed models and just keep one Item model with a "item_kind" flag to identify its type. Have each item define a relationship to another class based on this flag... (already sounds butt-ugly to me)
  • polymorphic relations (including the new N-2-N introduced in L 4.1) although they don't really seem to be thought for this specific scenario: especially N2N still doesn't solve the problem of accessing ALL the items via one simple relation
  • ditch the eager-loadable relation and write a custom "get_items()" method that would access the individual relationships (as in ->subitemones(), ->subitemtwos() etc ) but this seems like a rather dumb way to solve this problem (i really would like to be able to access the relationship within the query builder)

I'm kinda stuck here but I can't believe I'm the only one facing this situation... I'm really hoping for a "best practice" kind of suggestion here!

Pierlo Upitup
  • 1,614
  • 4
  • 19
  • 27

1 Answers1

0

You could consinder maping your class hierarcy to DB hierarcy. There are many ways to represent inheritance in your DB schema.

Considering your scenario you can have the following tables:

  • Set: This entity maps your parent class and stores all common information of a Set Item (eg Position etc)
  • SubItemOne: Extends the "set" entity, and stores only the additional information specific to this type.
  • SubitemTwo... etc

SubItemXXX have a 1:1 relationship with the Set entity. All you have to do is a simple JOIN to merge SubItemXXX and Set

You can read more at: How can you represent inheritance in a database?

Community
  • 1
  • 1
igaster
  • 12,983
  • 6
  • 26
  • 27