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

KillerCore's avatar

Database Structure

As i just started with laravel after not seeing any php for many years, i wanted to get on the forum and ask for some advice. Seeing this will be multiple joins and needs a good DB structure. Below are the relations.

Many Street -> Neighborhood

4 Neighborhoods -> Area

7 Area's -> City

Out of the users table

1 Person = Responsible for a Neighborhood

1 Person = Responsible for a Area

1 Person = Responsible for a City

There will be a search form. where you can select to search for people / Streets when it found the "LIKE" it should output the information that is linked to the person or street. for instance i look for Person A. which is responsible for Neighborhood A. and has a person above him that is Responsible for Area A.

Maybe someone could be so kind to get me a little started on the database to make it efficient.

0 likes
16 replies
KillerCore's avatar
City
id, name, user_id

Area
id, name, city_id, user_id

Neigborhood
id, name , area_id, user_id

Street
id, name, neigborhood_id, user_id

People
id, name, etc

Would this be a good way to link everything together?

Paschal's avatar
Paschal
Best Answer
Level 2

I would go with this approach.

  1. Create a Street table and model
  2. Create a Neighborhood table and model.
  3. Create an Area table and model.
  4. Create a City table and model.

Each of them will have a unique ID, in their migrations, they'll have this which will be their unique ID and primary key. The migrations will look like this:

//street_migration

<?php
.
.
.
Schema::create('street', function (Blueprint $table) {
    $table->increments('id');
    $table->name('name');
    $table->integer('neighborhood_id');
});

//neighborhood_migration

<?php
.
.
.
Schema::create('neighborhood', function (Blueprint $table) {
    $table->increments('id');
    $table->name('name');
    $table->integer('area_id');
    $table->integer('user_id')->unsigned();
});

//area_migration

<?php
.
.
.
Schema::create('area', function (Blueprint $table) {
    $table->increments('id');
    $table->name('name');
    $table->integer('city_id');
    $table->integer('user_id')->unsigned();
});

//city_migration

<?php
.
.
.
Schema::create('city', function (Blueprint $table) {
    $table->increments('id');
    $table->name('name');
    $table->integer('user_id')->unsigned();
});

You can as well implement foreign keys if you need one.

Now, I will proceed to add relationships in the models, I believe a Street can only belong to one Neighborhood.

So in the Street model, I have this:

<?php 

//App\Street
.
.
.

public function neighborhood(){
    return $this->belongsTo('App\Neighborhood');
}

While in the Neighborhood, a Neighborhood can only belong to one Area but have many Street and also be assigned to a User.

<?php 
//App\Neighborhood
.
.
.

public function streets(){
    return $this->hasMany('App\Street');
}

public function area(){
    return $this->belongsTo('App\Area');
}

public function user(){
    return $this->belongsTo('App\User');
}

An Area can have many Neighborhood but can only belong to one City and also be assigned to a User

So in the Area model, I have this:

<?php 
//App\Area
.
.
.
public function neighborhoods(){
    return $this->hasMany('App\Neighborhood');
}

public function city(){
    return $this->belongsTo('App\City');
}

public function user(){
    return $this->belongsTo('App\User');
}

Lastly, a City can have many Area and only belong to a User, so we have this in the City model:

<?php 
//App\City
.
.
.

public function areas(){
    return $this->belongsTo('App\Area');
}

public function user(){
    return $this->belongsTo('App\User');
}

Finally, for the User, we already have a user_id field for Neighborhood, City and Area and a relationship for each of them from those models. To access a User area, neighborhood or city, we add this to the User model:

<?php 
//App\User
.
.
.

public function neighborhood(){
    return $this->hasOne('App\Neighborhood');
}

public function area(){
    return $this->hasOne('App\Area');
}

public function city(){
    return $this->hasOne('App\City');
}

That, my friend is how you implement something like what you desire.

1 like
KillerCore's avatar

@paschal with the above models and database tables. i tried to get data from the tables but i am at a loss. If i load all Streets in a foreach list. is it possible to get for instance the Area->id / Neigborhood->name / Users->name ?

i seem to end up with multiple nested relationships and getting a weird collection of relation after relation.

KillerCore's avatar

Controller

$streets = Street::with('neigborhood', 'neighborhood.area', 'neighborhood.area.city', 'neigborhood.user')->get()->toArray();

return view('search', compact('streets'));

View

            @foreach ($streets as $street)
            <tr>
                <td>{{ $street['name'] }}</td>
                <td>{{ $street['neighborhood']['area']['city']['id'] }}</td>
                <td>{{ $street['neighborhood']['name'] }}</td>
                <td>{{ $street['neighborhood']['user']['name'] }}</td>
                <td>0612345678</td>
            </tr>
            @endforeach
    

This seems to output the correct info per row.

Paschal's avatar

Yes you can @killercore. You can just use chaining like this...

In your controller method, get the steeets

Street::get();

In your view, loop through the street variable.

@foreach ($streets as $street)
    <tr>
        <td>{{ $street->name }}</td>
        <td>{{ $street->neighborhood->area->city->id; }}</td>
        <td>{{ $street->neighborhood->name; }}</td>
        <td>{{ $street->neighborhood->user->name; }}</td>
        <td>0612345678</td>
    </tr>
@endforeach

There you go. I use objects instead of arrays.

KillerCore's avatar

Ha great that looks better. i am probably just trying to run instead of taking it slow. Ima make the search function and then just watch laracast more as if it was game of thrones.

I really appriciate your help @paschal thanks

edit: with the above code it does load $street->name into the collection but if i do a DD it does not show any relations.

Paschal's avatar

How about the $street->neighborhood->name, does it load?

The way Model works can be tricky, did you check the relations when you dd'd and saw nothing?

KillerCore's avatar

Yeah the relations where empty, if i include with-> it does show, but then its street->relation->neigborhood->relation etc.

$Streets = Street::get();
dd($Streets);

gives
#relations: []

Edit:

$street->neighborhood->name works
$street->name works

$street->neighborhood->user->name does not work
$street->neighborhood->user['name'] work

anything deeper seems to give a Trying to get property of non-object

Paschal's avatar

Well, there you have it.

What do you mean by 'anything deeper', how deep are you trying to go?

The below should work too so far you set your relationship right and they contain data, else if it's null, you'll get the Trying to get property of non-object error.

$street->neighborhood->area->city->name;
KillerCore's avatar

i edited my last reply, maybe that makes more sence. ill check the relations maybe something go's wrong there.

Paschal's avatar

Well that's pretty strange. This should work:

$street->neighborhood->user->name //does not work

Dump the following in your controller and see if it returns a User model.

dd( $street->neighborhood->user );
KillerCore's avatar

With the above DD i get this.

Property [neighborhood] does not exist on this collection instance.

Which is weird cause in my view i can access $street->neighborhood just fine

Paschal's avatar

Well rollback and dd this

dd( $street->neighborhood );

See what it returns. If it does not return a Neighborhood collection, check that the relationship was defined well, including the foreign and local key.

KillerCore's avatar
dd( $street->neighborhood );

this return the neighborhood collection now. going to ->area after that gives a null. so i guess i need to play with the relationships foraign and local key

edit: haha @paschal i am such an asshat. i mixed up a number in the database. thats why the relationship failed +_+. can't believe i looked over it haha.

dd( $street->neighborhood->area->city );

works as well now.

Please or to participate in this conversation.