Jeff
Jeff

Reputation: 6663

Eloquent with multiple relations

I'm new to Laravel and ORMs in general, so this is probably a very basic concept that I'm missing. I have three tables that I'm trying to define a relation with using Laravel 4's Eloquent ORM. Here's the slimmed-down table definitions:

stores
id (PK)
name

postal_codes
id (PK)
postal_code
city
state
country

locations
id (PK)
store_id (FK => stores.id)
postal_code_id (FK => postal_codes.id)
*additional location-specific fields such as address, phone #, etc

The stores table has a one to many relationship with the locations table, so I can use $this->hasMany("Location") in the Stores model, and $this->belongsTo("Store") in the Location model.

My question is, how do I define the relation between locations and postal_codes in their respective models? The locations table has a many-to-one relationship with the postal_codes table. Ideally I want to be able to do something like this: $store->locations()->first()->city. Is this possible?

Upvotes: 0

Views: 2439

Answers (3)

Homme Sauvage
Homme Sauvage

Reputation: 1916

Aren't you looking for something like:

class Locations 
{
    public function city()
    {
        return $this->belongsTo('PostalCode');
    }
}

So now you can call $store->locations()->first()->city. This will return a PostalCode model, if you want to return just the city:

public function getCity()
{
    return $this->city()->city;
}

And then you call $store->locations()->first()->getCity().

You could go further and create a __get() magic method so it calls everything dynamically.

Upvotes: 1

user1669496
user1669496

Reputation: 33048

I believe you are looking for a polymorphic relation.

Modify your locations table to include id, imageable_id, imageable_type, and then whatever additional location information you need. The imageable_id field will contain the ID of whatever you are looking for in it's respective table and the imageable_type will be whatever the name of that model for that table is.

On your models...

Class Location extends Eloquent
{
    public function imageable()
    {
        return $this->morphTo();
    }
}

Class Store extends Eloquent
{
    public function locations()
    {
        return $this->morphMany('Location','imageable');
    }
}

Class PostalCode extends Eloquent
{
    public $table = 'postal_codes';
    public function locations()
    {
        return $this->morphMany('Location','imageable');
    }
}

And now, it's possible to retrieve all of the locations for the stores or postal codes with something like

$store = Store::find(1);
foreach($store->locations as $location)
{
    //
    echo $location->city;
}

$postalCode = PostalCode::find(1);
foreach($postalCode->locations as $location)
{
    //
    echo $location->city;
}

Upvotes: 0

searsaw
searsaw

Reputation: 3622

It sounds like you have a many-to-many relationship between Stores and Postal_Codes. This would be demonstrated this way in Laravel:

class Store extends Eloquent {
    public function postal_codes() {
        $this->belongsToMany('Postal_Code', 'location');
    }        
}

class Postal_Code extends Eloquent {
    public function stores() {
        $this->belongsToMany('Store', 'location');
    }        
}

For more info, try this link: Laravel Many-to-Many Relationships.

Upvotes: 0

Related Questions