Useful Tips to Handle Relationships in Laravel

Handling Relationships in Laravel can’t be a easy task for beginners . In this article you will learn  some useful tips Tomake it easier  . Let’s suppose that we are searching for the document number of a specific user. We will use the User and IdentityDocument entities we just saw. For the purpose of this example, imagine that you have a table identitydocuments with the following columns:

  • Number: This indicates the document number
  • Type: This indicates the document type
  • due_date: This indicates the due date of the document
  • City: This indicates the city where the document was released

Here’s the code to get the document identity number, starting from a User instance:

  $user = AppUser::where('first_name', '=', 'Francesco')->where('last_name', '=', 'Malatesta')->first();

  $identityDocumentNumber = $user->identityDocument->number;

If you echo $identityDocumentNumber, you will read the desired information. Nice, huh?

Well, this is the way Laravel and Eloquent deal with querying your relationships. Once you have defined it, all you have to do is to access it as a simple property or a method.

All the other queries will be executed automatically by Laravel. In fact, follow these simple instructions:

  $user = AppUser::where('first_name', '=', 'Francesco')->where('last_name', '=', 'Malatesta')->first();

  $identityDocumentNumber = $user->identityDocument->number;

You just executed these queries:

  // the user Francesco Malatesta as an ID = 1...
  select * from users where first_name = 'Francesco' AND last_name = 'Malatesta';

  select * from identitydocuments where user_id = 1

Now put the result in to the $identityDocumentNumber. It is quite obvious for a one-to-one relationship; however, the same applies for a one-to-many relationship.

Let’s consider another example right now: good old Jules will be a perfect fit. Let’s suppose that we want to get a list of every Jules Verne books we have, and the code is as follows:

  $author = AppAuthor::where('first_name', '=', 'Jules')->where('last_name', '=', 'Verne')->first();

  foreach($author->books as $book)
  {
    echo $book->title . <br/>;
  }

  // outputs:
  //
  // Journey to the Center of the Earth
  // Twenty Thousand Leagues Under the Sea
  // Around the World in Eighty Days
  // Michel Strogoff

Note

As I told you before, you can have access to your relationship using a simple attribute or a method call. What’s the difference? Well, with the method call, you can do some filtering, and everything you saw before, in order to get the desired result. In fact, you can raise a query on a relationship.

Imagine that we want to get all the books with a the in the title. Here’s the code:

  $author = AppAuthor::where('first_name', '=', 'Jules')->where('last_name', '=', 'Verne')->first();

  $theBooks = $author->books()->where('title', 'LIKE', '%the%')->get();

  foreach($theBooks as $book)
  {
    echo $book->title . <br/>;
  }

  // outputs:
  //
  // Journey to the Center of the Earth
  // Twenty Thousand Leagues Under the Sea
  // Around the World in Eighty Days

Cool, right? It’s not over yet, this is just scratching the surface!

Accessing a pivot table

Working with many-to-many relationships, is not always about just defining a couple of external keys. You can choose to put extra data in to your pivot table in order to store some information for a specific connection between entities.

You already know how to create a pivot table, but how to access it? It’s nothing complex: all you have to do is to use the pivot attribute of your relationship. Let’s take an example using the previous books/categories relationship we created.

  1. First, you must define which attribute you want to take from the table, modifying the belongsToMany() call in your model:
      return $this->belongsToMany('AppCategory')->withPivot('created_at', 'notes');
  2. Then your code should be as follows:
      $book = AppBook::find(23);
    
      foreach($book->categories as $category)
      {
        echo 'Association Date: ' . $category->pivot->created_at;
        echo 'Association Notes: ' . $category->pivot->notes;
      }

In this little example, we just have printed all the dates that we attached a specific category to the book with id = 23. As an extra, we also printed some extra notes. This means that on the pivot table, we have the created_at and notes fields.

As a shortcut, you can also use:

  return $this->belongsToMany('AppCategory')->withTimestamps();

This is used if you just want to import timestamps data from the pivot table.

Querying a relationship

Eloquent allows you to query a relationship. In other words, you can get some results based on the existence of a certain relationship. Imagine that we want to get all the authors who have at least one book in the database.

With Eloquent, we can do something like this:

  $authorsWithABook = AppAuthor::has('books')->get();

In this case, you have to use the has method, specifying the name of the desired method for the relationship you want to check. The author will be added to $authorsWithABook only if at least one related book is be found.

If you don’t like this Boolean approach, don’t worry; let’s see how to find every author with at least five books in the database.

  $authorsWithAtLeastFiveBooks = AppAuthor::has('books', '>=', 5)->get();

Yeah, you can specify the second and third arguments as operator and comparison term, respectively, for this count check.

I know, I know, cool, but not enough. Alright, what about getting all the authors with at least one book dated 1864?

Here we go, this time with the whereHas method:

  $authorsWithABookFromThe1864 = AppAuthor::whereHas('books', function($q)
  {
      $q->where('year', '=', 1864);

  })->get();

As you can see, you can do it in a quite elegant way. The first parameter specified is the name of the relationship you want to query. The second argument is a closure that takes a $q query parameter, which you can use to define conditions.


 

About the author

Deven Rathore

I'm Deven Rathore, a multidisciplinary & self-taught designer with 3 years of experience. I'm passionate about technology, music, coffee, traveling and everything visually stimulating. Constantly learning and experiencing new things.

Pin It on Pinterest

Shares