chuysbz
chuysbz

Reputation: 1500

Eloquent model columns as properties

I am working with laravel and eloquent, I'm sorry if this is a stupid question, I've already made some search on google but couldn't find something like this.

I have a Company model which has a "hasMany" relationship with a CompanyProperties model. The CompanyProperties has two columns: "name" and "value".

id | Name           | Value
1  | primaryColor   | #000
2  | secondaryColor | #333

When I get the companies with Company::all(); it loads perfectly the CompanyProperties of each company. Every CompanyProperty returns a collection, which I can access using $company->CompanyProperties[0...n].

What I'd like to do if it's possible is that the CompanyProperties are accessible using the "name" column value as property or as an array. Using the example of my table above: $company->CompanyProperties['primaryColor'] or $company->CompanyProperties['secondaryColor']

Is there a way to do this?

Oh yea, many thanks in advance. I appreciate any advice you could have on this (even if I have to change the "properties" approach, haha).

Upvotes: 1

Views: 371

Answers (1)

andrewtweber
andrewtweber

Reputation: 25549

Laravel 5.1 and before: Use the lists method
Laravel 5.2: Use pluck

$properties = $company->companyProperties()->pluck('Value', 'Name');

This returns an array where the value is the the 1st argument ('Value') and the key is the 2nd argument ('Name'), e.g.

$value = $properties['primaryColor']; // '#000'

However, this can be pretty inefficient because you're running a query for each company that you fetch. If it's just one or a few companies that's ok but given that you're using Company:all() I would recommend eager loading:

$companies = Company::all();
$companies->load([
    'companyProperties'
]);

That will fetch the properties for all companies in a single query. Now for every $company, $company->companyProperties is a Collection. So you can use the keyBy method:

foreach ($companies as $company) {
    $properties = $company->companyProperties->keyBy('Name');

    $value = $properties['primaryColor']->Value; // '#000'
}

Notice that the syntax is slightly different, $properties['primaryColor'] is still a companyProperties object, so you have to get the attribute ->Value

Upvotes: 1

Related Questions