Reputation: 2616
I'm building a rudimentary CRM app using Laravel 6.0. Users can freely create accounts, but to get any functionality out of the app, they need to set up a SubscriptionAccount (or join an existing one), which will then allow them to create/manage customer Accounts, add Users, etc. (each is a one to many).
The User model's relationship to SubscriptionAccount model is giving me issues. For example:
$user = User::find(1);
$user->subscription()->create(['name' => 'Test Subscription']);
$user = $user->fresh();
dd($user->subscription); // returns null
I suspected it had to do with the belongsTo
relationship in the User model, but the odd thing is that it actually creates and persists a new SubscriptionAccount while using that relationship (second line above), though if you access users
relationship from the new SubscriptionAccount it also returns null.
Here are the models:
// User.php
class User
{
public function subscription()
{
return $this->belongsTo(SubscriptionAccount::class, 'subscription_account_id');
}
}
// SubscriptionAccount.php
class SubscriptionAccount extends Model
{
public function users()
{
return $this->hasMany(User::class, 'subscription_account_id');
}
}
The only thing out of the ordinary is shortening the name of the relationship to subscription
from SubscriptionAccount
, but that should have been taken care of by specifying the foreign key in both relationships. Here's the migrations:
Schema::create('subscription_accounts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->uuid('uuid')->unique();
$table->string('name');
$table->timestamps();
});
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->uuid('uuid')->unique();
$table->bigInteger('subscription_account_id')->unsigned()->index()->nullable();
$table->string('name');
...
$table->timestamps();
$table->foreign('subscription_account_id')
->references('id')
->on('subscription_accounts');
});
If I create the user from a SubscriptionAccount (i.e. $subscriptionAccount->users()->create([...]);
it sets the correct subscription_account_id
on the users
table, but doesn't work vice versa.
Upvotes: 0
Views: 2070
Reputation: 1678
This is a known issue (feature?) with the belongsTo
relationship:
https://github.com/laravel/framework/issues/29978
To work around it you can associate the models manually:
$user = User::find(1);
$sub = Subscription::create(['name' => 'Test Subscription']);
$user->subscription()->associate($sub);
$user->save();
Upvotes: 2
Reputation: 14248
So instead of using belongsTo
because a subscription account does not belongs to one user, it can belong to many, you might want to use the hasOne
relationship instead:
public function subscription()
{
return $this->hasOne(SubscriptionAccount::class, 'id', 'subscription_account_id');
}
It will belongTo
one User if you had a user_id
within the subscription_accounts
table.
Let me know if it makes sense and if it works :)
Upvotes: 0