AlphaOmega
AlphaOmega

Reputation: 45

Laravel Eloquent getting data from relations

I have Task model. My Task model has some relationships and it currently looks like this:

class Task extends Model
{
    use HasFactory;

    public $timestamps = false;

    public function city()
    {
        return $this->hasOne(City::class, 'id', 'city_id');
    }

    public function type()
    {
        return $this->hasOne(Type::class, 'id', 'type_id');
    }

    public function note()
    {
        return $this->hasOne(Note::class, 'id', 'note_id');
    }

    public function operator()
    {
        return $this->hasOne(User::class, 'id', 'operator_id');
    }
}

Now, in my TasksController I need to get Tasks that match certain criteria, like this:

$tasks = Task::whereCityId($city->id)->whereTypeId($type->id)->get()->toArray();

The problem is that fields named city_id type_id note_id operator_id will get my integer values that they have.

Instead I would like to get certain value from a related Model.

For example:

operator_id should be replaced with username from User table that corresponds to the user id.

An obvious solution to this would be to simply use foreach loop, go through my results and get the data I need and simply create another array with the information replaced, but I am not sure if this is the best idea and perhaps there is something better.

Upvotes: 1

Views: 5243

Answers (3)

Surender Singh Rawat
Surender Singh Rawat

Reputation: 919

You have to change in your code:

$this->hasOne(ClassName::class, 'id', 'foreign_key');

To

$this->belongsTo(ClassName::class, 'foreign_key', 'id');

because Task's id does not available as foreign key in these tables. These table's id present in task table as foreign key so you have to use belongsTo() relationship to tell script from where these id belongs.

Then access properties like this:

$tasks = Task::with("type", "city", "operator")
->whereCityId($city->id)->whereTypeId($type->id)->get();

foreach($tasks as $task){
   echo $task->city->name;
}

Upvotes: 3

Muhamad Rafi Pamungkas
Muhamad Rafi Pamungkas

Reputation: 308

i think this will help better than what you ask.

$tasks = Task::whereCityId($city->id)
->whereTypeId($type->id)
->with('operator')
->get()->toArray();

with('operator') is ORM feature that make you collection to include its relation as collection property. In this case it will convert to array property.

you could access it from your foreach function as

@foreach($task as $key)
$key['operator']['username']
@endforeach

Have a nice day

Upvotes: 0

OMR
OMR

Reputation: 12218

first you should fix your relation:

public function city()
    {
        return $this->hasOne(City::class,'city_id','id'); 
    }

and so one the same error, foreign key in argument order comes before the primary key.

after that you can use addSelect:

 $tasks = Task::whereCityId($city->id)->whereTypeId($type->id)
            ->addSelect(['userName' => User::select('name')
                ->whereColumn('users.id', 'tasks.operator_id')
                ->limit(1)])->get()->toArray();

Upvotes: 0

Related Questions