It seems like you want to create a transaction that is associated with an account and also morphs to a specific model (either an Account or a PiggyBank). To achieve this in a clean way, you can use the create method on the transactions relationship and then manually set the morphable attributes.
Here's how you can do it:
// Assuming you have an Account instance and a morphable model instance (Account or PiggyBank)
$account = Account::find($accountId);
$morphableModel = PiggyBank::find($piggyBankId); // or another Account
// Create the transaction for the account
$transaction = $account->transactions()->create([
'name' => 'Transaction Name',
'price' => 100,
'external_credit' => false,
// You don't need to set 'account_id' as it's automatically set by the `transactions()` relationship
]);
// Now manually set the morphable attributes
$transaction->transactionable()->associate($morphableModel);
$transaction->save();
This way, you're explicitly setting the morphable model after creating the transaction. The associate method is used to set the transactionable_type and transactionable_id fields on the Transaction model.
If you find yourself doing this often, you could encapsulate this logic into a method on the Account model to keep your code DRY:
class Account extends Model
{
// ... existing methods ...
/**
* Create a transaction and associate it with a morphable model.
*/
public function createTransactionWithMorphableModel(array $transactionData, Model $morphableModel): Transaction
{
$transaction = $this->transactions()->create($transactionData);
$transaction->transactionable()->associate($morphableModel);
$transaction->save();
return $transaction;
}
}
Then you can use this method like so:
$account = Account::find($accountId);
$morphableModel = PiggyBank::find($piggyBankId); // or another Account
$transactionData = [
'name' => 'Transaction Name',
'price' => 100,
'external_credit' => false,
];
$transaction = $account->createTransactionWithMorphableModel($transactionData, $morphableModel);
This approach keeps your controllers or services clean and delegates the responsibility of creating the transaction with the morphable model to the Account model.