Ad

Laravel Relationship Count()

- 1 answer

I want to get a total user transaction (specific user) with relationship. I've done it but i'm curious is my way is good approach.

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

//Merchant Model

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

public function countTransaction()
{
    return $this->hasOne(Transaction::class)
        ->where('user_id', Request::get('user_id'))
        ->groupBy('merchant_id');
}

public function getCountTransactionAttribute()
{
    if ($this->relationLoaded('countTransaction'))
        $this->load('countTransaction');

    $related = $this->getRelation('countTransaction');

    return ($related) ? (int)$related->total_transaction : 0;
}

//controller

$merchant = Merchant::with('countTransaction')->get();

What make me curious is part inside countTransaction. I put where where('user_id', Request::get('user_id')) directly inside the model.

is it good approach or any other way to get specific way?

expected result:

"merchant:"{
    "name": "example"
    "username" : "example"
    "transactions": {
        "count_transactions: "4" //4 came from a specific user.
    }
}

I need to get the merchant data with the transaction count for specific user. This query is based on logged in user. so when a user access merchant page, they can see their transaction count for that merchant.

Thanks.

Ad

Answer

You really want to keep request data outside of your models (instead opting to pass it in). I'm also a little confused about why you have both a 'hasOne' for transactions, and a 'hasMany' for transactions within the merchant model.

I would probably approach the problem more like the below (untested, but along these lines). Again I'm not fully sure I understand what you need, but along these lines

    // Merchant Model
    public function transactions()
    {
        return $this->hasMany(Transaction::class);
    }

    public function countTransactionsByUser($userId)
    {
        return $this
                ->transactions()
                ->where('user_id', $userId)
                ->get()
                ->pluck('total_transaction')
                ->sum();
    }

    // Controller

    $userId = request()->get('user_id');

    // ::all() or however you want to reduce 
    // down the Merchant collection
    //
    $merchants = Merchant::all()->map(function($item, $key) {
        $_item = $item->getAttributes();
        $_item['transactions'] = [
            'count_transactions' => $item->countTransactionsByUser($userId);
        ];
        return $_item;
    });

    // Single total
    // Find merchant 2, and then get the total transactions 
    // for user 2
    //
    $singleTotal = Merchant::find(2)
        ->countTransactionsByUser($userId); 
Ad
source: stackoverflow.com
Ad