За последние 24 часа нас посетили 22310 программистов и 1023 робота. Сейчас ищет 651 программист ...

Как получить объект, связанный отношением?

Тема в разделе "Laravel", создана пользователем Nemoj, 27 окт 2020.

  1. Nemoj

    Nemoj Новичок

    С нами с:
    14 авг 2020
    Сообщения:
    30
    Симпатии:
    0
    Хочу таблицу Contacts в которой поле Company - объект из другой таблицы

    Вот я создал две модели

    Код (Text):
    1.  
    2. <?php
    3.  
    4. namespace App\Models;
    5.  
    6. use Illuminate\Database\Eloquent\Factories\HasFactory;
    7. use Illuminate\Database\Eloquent\Model;
    8. use Illuminate\Database\Eloquent\SoftDeletes;
    9.  
    10. class Contact extends Model
    11. {
    12.     use HasFactory;
    13.     use SoftDeletes;
    14.     protected $guarded = [];
    15.  
    16.     protected $table = 'contacts';
    17.     public $timestamps = true;
    18.  
    19.     /**
    20.      * The model's default values for attributes.
    21.      *
    22.      * @var array
    23.      */
    24.     protected $attributes = [
    25.         'name' => ''
    26.     ];
    27.  
    28.     public $appends = [
    29.         'company'
    30.     ];
    31.  
    32.     public function company()
    33.     {
    34.         return $this->belongsTo('App\Models\Company');
    35.     }
    36.  
    37.     public function getCompanyAttribute() // эту функцию вставил, потому что без нее ругалось
    38.     {
    39.         return 'XXX';
    40.     }
    41.  
    42. }
    43. }
    Код (Text):
    1. <?php
    2.  
    3. namespace App\Models;
    4.  
    5. use Illuminate\Database\Eloquent\Factories\HasFactory;
    6. use Illuminate\Database\Eloquent\Model;
    7. use Illuminate\Database\Eloquent\SoftDeletes;
    8.  
    9. class Company extends Model
    10. {
    11.     use HasFactory;
    12.     use SoftDeletes;
    13.     protected $guarded = [];
    14.  
    15.     protected $table = 'companies';
    16.     public $timestamps = true;
    17.  
    18.     /**
    19.      * The model's default values for attributes.
    20.      *
    21.      * @var array
    22.      */
    23.     protected $attributes = [
    24.         'name' => ''
    25.     ];
    26.  
    27.     public function contacts()
    28.     {
    29.         return $this->hasMany('App\Models\Contact');
    30.     }
    31.  
    32. }
    Вот миграции


    Код (Text):
    1. <?php
    2.  
    3. use Illuminate\Database\Migrations\Migration;
    4. use Illuminate\Database\Schema\Blueprint;
    5. use Illuminate\Support\Facades\Schema;
    6.  
    7. class CreateCompaniesTable extends Migration
    8. {
    9.     /**
    10.      * Run the migrations.
    11.      *
    12.      * @return void
    13.      */
    14.     public function up()
    15.     {
    16.         Schema::create('companies', function (Blueprint $table) {
    17.             $table->id();
    18.             $table->timestamps();
    19.             $table->softDeletes();
    20.             $table->string('name')->nullable();
    21.         });
    22.     }
    23.  
    24.     /**
    25.      * Reverse the migrations.
    26.      *
    27.      * @return void
    28.      */
    29.     public function down()
    30.     {
    31.         Schema::dropIfExists('companies');
    32.     }
    33. }

    Код (Text):
    1. <?php
    2.  
    3. use Illuminate\Database\Migrations\Migration;
    4. use Illuminate\Database\Schema\Blueprint;
    5. use Illuminate\Support\Facades\Schema;
    6.  
    7. class CreateContactsTable extends Migration
    8. {
    9.     /**
    10.      * Run the migrations.
    11.      *
    12.      * @return void
    13.      */
    14.     public function up()
    15.     {
    16.         Schema::create('contacts', function (Blueprint $table) {
    17.             $table->id();
    18.             $table->timestamps();
    19.             $table->softDeletes();
    20.             $table->string('name')->nullable();
    21.             $table->foreignId('company_id')->nullable()->constrained();
    22.         });
    23.     }
    24.  
    25.     /**
    26.      * Reverse the migrations.
    27.      *
    28.      * @return void
    29.      */
    30.     public function down()
    31.     {
    32.         Schema::dropIfExists('contacts');
    33.     }
    34. }
    Теперь хочу вывести на форму название контакта и соответствующую компанию.
    Код (Text):
    1.  
    2.         $contact = \App\Models\Contact::find(1);
    3.         $company = $contact->company;
    Сначала не выводило сосем, ругалось, что не найден метод getCompanyAttribute
    Я вставил такой метод. Теперь выводит XXX. Я пробовал писать на месте XXX так:
    $self->company
    Ругалось, Undefined property: App\Models\Contact::$company

    Как получить связанную компанию?
     
  2. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    1. Судя по всему у вас тут связь один (компания) ко многим (контакты)
    поэтому надо сначала в модель компании добавить связь

    Код (Text):
    1. public function contacts(): HasMany
    2. {
    3.      return $this->hasMany(Contact::class);
    4. }
    а в модель контактов добавить принадлежность
    Код (Text):
    1. public function company(): BelongsTo
    2. {
    3.      return $this->belongsTo (Company::class)
    4. }
    и тогда из модели компании вы сможете получить все контакты в коллекции $company->contacts

    вот тут подробнее https://laravel.com/docs/8.x/eloquent-relationships
     
  3. Nemoj

    Nemoj Новичок

    С нами с:
    14 авг 2020
    Сообщения:
    30
    Симпатии:
    0
    Вы правы, связь такая. И я так все и сделал.
    У меня не работало из-за строчки

    1. public $appends = [
    2. 'company'
    3. ];
    Убрал и заработало $contact->company

    Но мне нужно получать список всех полей. Я его беру в массив и перебираю. Как мне в этот массив брать связи?
     
  4. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    Добавьте
    PHP:
    1. public $with = ['company'];
     
    Nemoj нравится это.
  5. Nemoj

    Nemoj Новичок

    С нами с:
    14 авг 2020
    Сообщения:
    30
    Симпатии:
    0
    Спасибо. А как получить список полей объекта?
    Включая связанные объекты.