Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

oliverbusk's avatar

hasMany relationship, but only allow one "active record"

Hi everyone!

I am building an application, where users can control their rental properties / leases. For each lease, a user can attach a connection to their bank account (to automatically import recent transactions).

A lease can have many bank accounts attached.

//Lease.php
/**
* A lease can have many bank accounts attached 
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function bankAccounts(): \Illuminate\Database\Eloquent\Relations\HasMany
{
    return $this->hasMany(BankAccount::class);
}

Further, a bank account can have many transactions attached to it.

//BankAccount.php
/**
* A bank account can have many bank transactions.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function transactions()
{
     return $this->hasMany(BankTransaction::class);
}

For a lease, a user can change the associated bank account. In this scenario, I don't want to delete the transactions already imported (as these can be used elsewhere in the application), but just add the new bank account to the applicaton, and mark it as the "active" one.

How can I best do this, while also always ensuring that, I only have one active bank account per lease?

I was thinking of adding this method to the Lease model, and adding an is_active column to the database schema:

/**
* A lease can only have one active bank account.
*
*/
public function bankAccount()
{
    return $this->bankAccounts()->firstWhere('is_active', TRUE);
}

However, I am not sure how I can enforce/control that a lease can only have one active bank account?

0 likes
8 replies
koramit's avatar

I would add a file 'active_bank_id' to a Lease model.

Then create a relationship like this,

// Lease model
public function activeBank()
{
  return $this->belongsTo(Bank::class, 'active_bank_id')
}

Now I can use $lease->activeBank to get an active bank for a lease.

1 like
Snapey's avatar

your current relationship is has many, but can be done with hasOne

// Lease model
public function activeBank()
{
  return $this->hasOne(Bank::class)->where('isActive',true);
}
1 like
oliverbusk's avatar

But in my database, a Lease can have many BankAccounts, e.g.:

//table name: bank_accounts
id | lease_id | name                    | is_active
-------------------------------------------------------------
1  | 1        | Savings account         | 1
2  | 1        | Personal checkings      | 0
2  | 1        | Food and other expenses | 0

So changing the relationship to the below should work?

/**
* A lease can only have one active bank account.
*
*/
public function activeBankAccount()
{
    return $this->hasOne(BankAccount)->where('is_active', true);
}

Is there any way I can enforce that in the bank_accounts table, there can only be one record with is_active under the same lease id?

oliverbusk's avatar

How would you solve this using the new ofMany addition? I only see that I can use aggregators, and not something like:

public function activeBankAccount()
{
     return $this->hasOne(BankAccount::class)->ofMany([
         'is_active' => true,
     ]);
}
Snapey's avatar

if your active flag is 0 or 1 then max gives you the active one

return $this->hasOne(Order::class)->ofMany('is_active', 'max');

but tby, I would probably use the hasOne with where statement I mentioned earlier.

1 like

Please or to participate in this conversation.