1

Imagine following DB tables:

Clients                         Users
| Id | name  | user_id |        | ID | name   |
| -- | ----- | ------  |        | -- | ------ |
| 1  | NULL  | 1       |        | 1  | David  |
| 2  | Peter | NULL    |        

Not each client is automatically user, but user may have client account. Users table contains only registered users, if user is client (dont have to be) the client account is created.

I have succcessfully made relations between these table is Laravel. Eloquent querying woks fine, eg.:

clients.php

public function userAcc() {
    return $this->hasOne('User', 'id', 'user_id');
}

user.php

public function clientAcc() {
    return $this->hasOne('Clients', 'user_id', 'id');
}

The problem is that when i query these tables:

Clients::with('userAcc')->get()

In view i have to make lots of ifs, like:

@if($client->userAcc)
    {!! $client->userAcc->name !!}
@else
    {!! $client->name !!}
@endif

Is there any workaround in laravel that allows me to format collections on each select query? Something like Accessor but on whole collection, so i will be able to do something like this in view:

{!! $client->realname !!}

And it writes client name from particular table.

Many thanks for any suggestions

SirInfant
  • 323
  • 2
  • 3
  • 11

2 Answers2

2

You can make a method for that:

public function getName()
{
  return $this->userAcc?$this->userAcc->name:$this->name;
}

In your blade just call the function:

{{$client->getName()}}
Mina Abadir
  • 2,951
  • 2
  • 15
  • 20
  • Works like charm many thanks @Mina Youssef, one last thing what about AJAX calls (returning JSON) do you have any suggestions how to solve it? I mean that Clients::with('userAcc')->get()->toJson(); ... – SirInfant Dec 03 '15 at 14:20
  • 1
    You can take this a step further and make it an attribute, which would allow you to use it in the way you described: `public function getRealnameAttribute(){ return $this->userAcc?$this->userAcc->name:$this->name; }` then you can access it using `$client->realname` @SirInfant You can also access this using the toJson function by adding the appends attribute to the model. `public $appends = ['realname']` Then the ->toJson() function will include realname – Jeff Dec 03 '15 at 14:23
  • This probably won't work, as custom accessors won't be returned in toArray(). You need to override toArray() method, and add the new custom accessor to it. – Mina Abadir Dec 03 '15 at 14:25
  • Please check this as well http://stackoverflow.com/questions/17232714/add-a-custom-attribute-to-a-laravel-eloquent-model-on-load – Mina Abadir Dec 03 '15 at 14:26
2

This is the Laravel way to accomplish this:

class Client extends Model {

public $appends = ['realname'];

public function userAcc() {
    return $this->hasOne('User', 'id', 'user_id');
}

public function getRealnameAttribute(){
    return $this->userAcc? $this->userAcc->name : $this->name;
}

Now it will be accessible through $client->realname and it will be included in $client->toJson() and $client->toArray()

Steve O
  • 5,224
  • 1
  • 24
  • 26
Jeff
  • 24,623
  • 4
  • 69
  • 78