ssuhat
ssuhat

Reputation: 7656

Laravel relationship count()

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.

Upvotes: 4

Views: 876

Answers (1)

Chris
Chris

Reputation: 58322

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); 

Upvotes: 1

Related Questions