0
\$\begingroup\$

I am using Laravel 5.3, and currently working on models.

I have the following code:

$result = TheEpisode::find($id)->with('TheParts')->take(1)->get()->each(function ($item) {
      $item->TheParts->makeHidden("title");
});

The purpose of this code is to display all the data from TheEpisode and TheParts, but exclude the title from there.

Can this be improved, like not using a loop to exclude the title attribute?

\$\endgroup\$
1
\$\begingroup\$

no need to loop as you are using find method and find method always give single result

$result = TheEpisode::find($id);
$result->TheParts->makeHidden("title");
dd($result->toArray());
\$\endgroup\$
1
  • \$\begingroup\$ TheParts has multiple values, are you sure makeHidden will work on multiple values? \$\endgroup\$
    – PHP Lover
    Dec 13 '16 at 12:34
1
\$\begingroup\$

First of all, it is important to note that, you are making 2 different queries by doing something like find($id)->with(...)

  1. The reason behind this is -> find($id) performs the SELECT * FROM WHERE ID = ... query and the object of model is returned.
  2. Now once again, after getting $model you are performing the with() function of the query builder which finally makes another query.

For more optimization, please prefer the below code.

$item = TheEpisode::with('TheParts')->find($id);

$item->TheParts->transform(function($part) {
  $part->makeHidden('title');
  return $part;
});
  1. Line 1 performs only 1 query which returns the model.
  2. When you do $item->TheParts, based on your relation, you'll get a collection/model. Since An episode can have multiple parts, I am going to consider it a HasMany relation and therefore you get a collection.
  3. Finally, you perform transform (documentation here) which modifies the collection itself.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy