8

I have a relation one to many between users table and areas table , when i return profile data i get area_id from users table, i need to get area name using models. Is there a way to get area name in profile view ? I tried to call model function in show.vue but it is not working.

User.php

 public function area()
    {
        return $this->belongsTo(Area::class);
    }

Area.php

 public function users()
    {
        return $this->hasMany(User::class);
    }

show.vue

<template>
    <app-layout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">
                Profile
            </h2>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">
                Area : 
            </h2>
        </template>

        <div>
            <div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
                <div v-if="$page.props.jetstream.canUpdateProfileInformation">
                    <update-profile-information-form :user="$page.props.user" />

                    <jet-section-border />
                </div>

                <div v-if="$page.props.jetstream.canUpdatePassword">
                    <update-password-form class="mt-10 sm:mt-0" />

                    <jet-section-border />
                </div>

                <div v-if="$page.props.jetstream.canManageTwoFactorAuthentication">
                    <two-factor-authentication-form class="mt-10 sm:mt-0" />

                    <jet-section-border />
                </div>

                <logout-other-browser-sessions-form :sessions="sessions" class="mt-10 sm:mt-0" />

                <template v-if="$page.props.jetstream.hasAccountDeletionFeatures">
                    <jet-section-border />

                    <delete-user-form class="mt-10 sm:mt-0" />
                </template>
            </div>
        </div>
    </app-layout>
</template>

<script>
    import AppLayout from '@/Layouts/AppLayout'
    import DeleteUserForm from './DeleteUserForm'
    import JetSectionBorder from '@/Jetstream/SectionBorder'
    import LogoutOtherBrowserSessionsForm from './LogoutOtherBrowserSessionsForm'
    import TwoFactorAuthenticationForm from './TwoFactorAuthenticationForm'
    import UpdatePasswordForm from './UpdatePasswordForm'
    import UpdateProfileInformationForm from './UpdateProfileInformationForm'

    export default {
        props: ['sessions'],

        components: {
            AppLayout,
            DeleteUserForm,
            JetSectionBorder,
            LogoutOtherBrowserSessionsForm,
            TwoFactorAuthenticationForm,
            UpdatePasswordForm,
            UpdateProfileInformationForm,
        },
    }
</script>
samarsamy92
  • 113
  • 1
  • 10
  • please share your schema. and controller code. – rameezmeans Mar 04 '21 at 21:31
  • mainly people try to access model function like this $user->area(); which is entirely wrong. right way is $user->area; without curly braces. – rameezmeans Mar 04 '21 at 21:38
  • i get user object via vue component so i can not use "$user->area " – samarsamy92 Mar 04 '21 at 21:50
  • 1
    try using "user.area". does "user.name" work fine? – rameezmeans Mar 04 '21 at 22:04
  • user.area prints no thing ): , user.name prints user name. this is example of user obj : { "id": 2, "fname": "", "lname": "", "email": "test@test.com", "email_verified_at": "2021-02-22T22:44:50.000000Z", "current_team_id": 2, "area_id": 2, "profile_photo_path": null, "created_at": "2021-02-22T22:36:14.000000Z", "updated_at": "2021-03-04T21:02:38.000000Z", "profile_photo_url": "https://ui-avatars.com/api/?name=&color=7F9CF5&background=EBF4FF", "two_factor_enabled": false } – samarsamy92 Mar 04 '21 at 22:21
  • "user.area.name" does it work? i want to see schema and controller function as well. from where you are calling this function. – rameezmeans Mar 04 '21 at 22:54
  • it is built in laravel inertia functions , i really do not know how it working , so i can not handle it . i just added new table "area" – samarsamy92 Mar 04 '21 at 23:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/229536/discussion-between-r89human-and-samarsamy92). – rameezmeans Mar 04 '21 at 23:09

3 Answers3

8

You need to load all relationships you want to display manually. Unlike in Blade you can’t just access the relationship with $user->area because $user is not an Eloquent instance but what you are returning as JSON to your Vue instance.

From your controller call $user->load('area'). This will make area available to you.

Tim
  • 5,893
  • 3
  • 35
  • 64
1

Controller.php:

 $doctors = User::with('area')->paginate(5);

Vuefile.js

 {{user.area.name}}
mante
  • 87
  • 1
  • 9
0

I had the same problem, but finally i found another trick, I defined another method in my model and added an attribute

In your case: Try this: Area.php

class Area extends Model
{ ....
   $appends = ['users'];

   public function users()
    {
        return $this->hasMany(User::class);
    }
    
   // define a methode getUsersAttribute()
   public function getUsersAttribute(){
      return $this->users()->get();
   }
  
  • Careful: using this code, all Area's users will be loaded every time a single/many Area(s) is/are loaded. Without any pagination or limitation. This will be very resource greedy. Look at @Tim answer: you need to load the relationship with Eloquent before it's returned as JSON to the view/JS. – Mtxz Aug 24 '21 at 00:01