Ссылка пользователя на профиль Laravel 5.6

Я очень новичок в Laravel и хотел бы внести ясность.

Я пытаюсь связать две таблицы: Users => Profiles

Users выглядит так:

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('username');
    $table->string('displayName');
    $table->string('email')->unique();
    $table->string('role')->nullable();
    $table->string('department')->nullable();
    $table->string('location')->nullable();
    $table->string('directDialIn')->nullable();
    $table->string('mobileNumber')->nullable();
    $table->string('managedByUsername')->nullable();
    $table->string('managedByDisplayName')->nullable();
    $table->timestamps();
});

Profiles выглядит так:

Schema::create('profiles', function (Blueprint $table) {
    $table->increments('id');
    $table->string('user_username')->index();
    $table->mediumText('skills');
    $table->mediumText('background');
    $table->mediumText('socialProfiles');
    $table->string('displayPicture')->default('../../assets/images/user_pic.jpg');
    $table->string('mangedByUsername');
    $table->boolean('changesPending')->default(0);
    $table->timestamps();
}); 

Соответствующие модели

class User extends Authenticatable
{
    use Notifiable;

    /**
     * Primary key to use
     */
    protected $primaryKey = 'username';

    /**
     * Tell Eloquent to not auto increment
     */
    public $incrementing = false;

    /**
     * Table to use
     */
    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'username', 'displayName', 'email', 
        'role', 'department', 'location', 
        'directDialIn', 'mobileNumber', 'managedByUsername',
        'managedByDisplayName'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * Get the profile associated with this user
     */
    public function profile()
    {
        return $this->hasOne(Profile::class, 'user_username');
    }
}

class Profile extends Model
{
    /**
    * Get the user that has this Profile
    */
    public function user()
    {
        return $this->belongsTo(User::class, 'user_username');
    }
}

Согласно документации:

Eloquent определяет внешний ключ отношения на основе имени модели. В этом случае автоматически предполагается, что модель Phone имеет внешний ключ user_id. Если вы хотите переопределить это соглашение, вы можете передать второй аргумент методу hasOne:

Поэтому я явно определил используемые ключи.

В моих маршрутах у меня есть:

Route::get('/profile/{user}', 'ProfileController@index');

Я привык просто соединять две таблицы с помощью SQL JOIN, но в этом случае, как мне получить как данные модели пользователя, так и данные модели профиля?

Таким образом, это будет выглядеть так: Пользователь: Дэйв, затем профиль Дэйва.

Кроме того, если Дэйв не заполнил свой профиль, могу ли я отобразить только его пользовательские данные?

В ProfilesController у меня есть это:

public function index(Request $request)
{
    // Get this user's username from the session
    $username = $request->session()->get('User_name');

    /**
     * Get the Profile and associated User by pulling from the database via user_username
     * Will return a profile with an attached user
     */
    $profile = Profile::with('user')->where('user_username', $username)->first();

    return view('pages.profile.show', compact('profile'));
}

Однако, когда я вывожу результат для Profile, связанный с ним User равен нулю.

Я нахожу это странным, поскольку я могу использовать Artisan tinker следующим образом:

$profile = App\Profile::find(7);

а потом...

$profile->user

Что дает пользователю, относящемуся к профилю с идентификатором 7.

dd($profile); дает следующее:

введите здесь описание изображения

Таблица профилей

введите здесь описание изображения

Таблица пользователей

введите здесь описание изображения

Как видите, данные есть в обеих таблицах, и user_username совпадает с username, но по какой-то причине при использовании with:: связь между ними просто не видна.


person Jesse Orange    schedule 17.04.2018    source источник
comment
Какой внешний ключ в модели Profile? Если это user_username, вы должны указать его в своей модели или отношении. Потому что Eloquent определяет внешний ключ отношения на основе имени модели. В этом случае автоматически предполагается, что модель профиля имеет внешний ключ user_id.   -  person iamab.in    schedule 17.04.2018
comment
Я обновлю свой вопрос, чтобы показать более подробную спецификацию   -  person Jesse Orange    schedule 17.04.2018
comment
у вашего $profile есть данные? Как получить доступ к отношениям? Это как $profile->user ?   -  person iamab.in    schedule 17.04.2018
comment
Я именно так и пытаюсь.   -  person Jesse Orange    schedule 17.04.2018
comment
пожалуйста, добавьте dd($profile); результат из index() метода. перед заявлением о возврате.   -  person iamab.in    schedule 18.04.2018
comment
Я добавлю это к ответу.   -  person Jesse Orange    schedule 19.04.2018
comment
Вы можете добавить несколько строк таблицы для обеих таблиц? Вы уверены, что есть пользователь с username = jesseo ? Ничто другое, кажется, не имеет проблемы!   -  person iamab.in    schedule 19.04.2018
comment
Я сделал несколько тестов, и все работает отлично, когда отношение определено как public function user() { return $this->belongsTo(User::class, 'user_username', 'username'); }, но возвращает ноль, когда отношение определено как public function user() { return $this->belongsTo(User::class, 'user_username''); }. Я не могу найти никакой другой причины состояния null.   -  person iamab.in    schedule 19.04.2018


Ответы (1)


Используйте метод with()

$profile_with_user = Profile::with('user')->where('user_username', $username)->first();

Or

$user_with_profile = User::with('profile')->where('username', $username)->first();
person Sohel0415    schedule 17.04.2018
comment
Итак, в этом смысле, если я использую модель профилей, не лучше ли использовать первый экземпляр? - person Jesse Orange; 17.04.2018