Laravel 5.6. Вложенные красноречивые отношения - PullRequest
0 голосов
/ 29 августа 2018

Доброе утро, сейчас я изучаю модель отношений, работая над проектом, связанным с игрой. У меня есть модель банка с отношением hasMany к модели транзакций

Schema::create('banks', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name',30);
        $table->string('faction',10);
        $table->string('region',3);
        $table->integer('balance')->unsigned()->nullable();
        $table->timestamps();
        $table->softDeletes();
    });

Модель:

class Bank extends Model
{
   use SoftDeletes;

   /**
   * Establishes a oneToMany relationship with the Transaction
   * model
   *
   * @param
   * @return
   */
   public function transactions()
   {
       return $this->hasMany('App\Transaction');
   }
}

Схема транзакции:

Schema::create('transactions', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('bank_id')->unsigned();
        $table->integer('user_id')->unsigned();
        $table->integer('operator_id')->unsigned();
        $table->string('operation', 128);
        $table->integer('amount');
        $table->string('note',255)->nullable();
        $table->timestamps();
        $table->softDeletes();

        $table->foreign('bank_id')
              ->references('id')
              ->on('banks')
              ->onUpdate('cascade');

        $table->foreign('user_id')
              ->references('id')
              ->on('users')
              ->onUpdate('cascade');

        $table->foreign('operator_id')
              ->references('id')
              ->on('users')
              ->onUpdate('cascade');

    });

Схема пользователя:

Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });

Модель транзакции:

class Transaction extends Model
{
use SoftDeletes;

public function banks()
{
    return $this->belongsTo('App\Bank');
}

public function users()
{
    return $this->belongsTo('App\User');
}
}

Я бы хотел добиться в Laravel следующего SQL:

SELECT t.amount, t.created_at, b.name, b.region, b.faction, u.name 
FROM transactions as t
JOIN users as u
JOIN banks as b ON t.bank_id = b.id
WHERE b.id =1
ORDER by t.created_at DESC

Мне удалось написать это, которое возвращает все транзакции из выбранного банка, в данном случае 1 (но это в конечном итоге передается через параметр)

public function show($bank)
{
    $transactions = Bank::find($bank)->transactions()
                                     ->orderBy('created_at','DESC')
                                     ->get();
    dd($transactions);
}

Но я понятия не имею, как получить остальную часть моего SQL. Любая помощь оценена с небольшим количеством объяснения.

Загрузка скриншота Json этого DD: Json

Как я могу получить поле user.name этих двух user_id и operator_id в атрибутах? с Eloquent, а не с qBuilder

Ответы [ 4 ]

0 голосов
/ 30 августа 2018

Я исправил код следующим образом:

$transactions = Transaction::with(['user', 'bank'])
                                ->where('bank_id',1)
                                ->limit(10)
                                ->get();
    //dd($transactions);

Я также изменил отношение Модель транзакции:

class Transaction extends Model
{
    use SoftDeletes;

    public function bank()
       {
          return $this->belongsTo('App\Bank');
       }

    public function user()
       {
         return $this->belongsTo('App\User');
       }
}

Так как они возвращают только одну модель.

0 голосов
/ 29 августа 2018

Я рекомендую использовать отношения BelongsToMany:

class Bank extends Model {
    public function users() {
        return $this->belongsToMany(User::class, 'transactions')
            ->withPivot('amount')
            ->orderByDesc('transactions.created_at');
    }
}

foreach($bank->users as $user) {
    // $user->name
    // $user->pivot->amount
}
0 голосов
/ 29 августа 2018

Вы можете сделать что-то вроде:

$transactions = \App\Transaction::with('bank', 'user')
    ->where('bank_id', $bank)
    ->orderBy('created_at', 'desc')
    ->get();

Метод with() загружает отношения в модель. Затем вы можете рассматривать отношения как свойства для доступа к информации из них, например

foreach ($transactions as $transaction) {

    $transaction->amount;

    $transaction->user->name;

    $transaction->bank->name;
    $transaction->bank->region;

}

Для получения дополнительной информации, пожалуйста, ознакомьтесь с документацией .

0 голосов
/ 29 августа 2018

Поместите этот метод в модель транзакции, он должен работать

 public function getByBankId($id)
    {
        return $this
            ->join("banks as b", "b.id", "=", "transactions.bank_id")
            ->join("users as u", "u.id", "=", "transactions.user_id")
            ->where("b.id", $id)
            ->orderBy("transactions.created_at", "DESC")
            ->selectRaw("transactions.amount, t.created_at, b.name, b.region, b.faction, u.name")
            ->get();
    }
...