I try to delete categories of user like as:
Category::with('user', Auth::user()->id)->where("user_id", $id)->delete();
Category model has relationship:
public function user()
{
return $this->belongsTo('App\User', 'user_id', 'id');
}
But it does not work for me
User model:
public function categories()
{
return $this->belongsToMany('App\Category');
}
Try without with():
Category::where("user_id", $id)->delete();
Update after the User model code addition:
The inverse of a belongsToMany relation is another belongsToMany, the inverse of a belongsTo is a hasMany or a hasOne.
You have to decide which relations between User and Category you want, because a belongsTo doesn't work with an inverse belongsToMany.
From what you wrote in answer and comments seems that you want a Many to many relationship (you have an intermediate table) in this case you have to use belongsToMany in both models and then you can use this code to delete user categories assignement:
$user->categories()->detach()
I think you need to flesh out how they will relate. Right now, based on your relationship code, the Categories table should have an user_id in it.
This is what the relationship on the Category model should look like:
public function users()
{
return $this->belongsToMany(User::class);
}
And you need a table with the name category_user to make the relationship work. Here's an example of what the migration would look like:
Schema::create('category_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamps();
$table->foreign('category_id')->references('id')->on('categories');
$table->foreign('user_id')->references('id')->on('users');
})
Then you'd be able to add users to categories in the following ways:
$category->users()->attach(Auth::id());
Auth::user()->categories()->attach([ 1, 2, 3 ... ]);
And remove:
$category->users()->detach(Auth::id());
Auth::user()->categories()->detach([ 1, 2, 3 ... ]);
You can also use sync which would detach any element not on your array and attach any element not currently attached:
Auth::user()->categories()->sync([ 1, 2, 3, ... ]);
Related
I am trying to select the picture with the most likes within a specific category from my database. I have a database table storing the pictures and a table storing the likes. The pictures table is related to likeable table through a hasMany polymorphic relationship.
Like model:
public function likeable()
{
return $this->morphTo();
}
Picture model:
public function likes()
{
return $this->morphMany('App\Like', 'likeable');
}
Home Controller:
Picture::where('picture_type', 'food')->orderBy(likes(), 'desc')->first();
Likeable Migration:
public function up()
{
Schema::create('likeable', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->integer('likeable_id');
$table->string('likeable_type');
$table->timestamps();
});
}
So far, the above line of code, in my home controller returns an error. From what I understand, the likes method has to be called on a specific instance. However, I do not know how to implement this all the while keeping my where clause.
Thank you for your help.
I assume you are wanting to order pictures by the most likes.
In which case, you want something like this:
Picture::withCount('likes')->where('picture_type', 'food')->orderBy('likes_count', 'desc')->first();
i have three tables cart , cart_products , products
i have that relation in cart table
public function products()
{
return $this->hasManyThrough(Product::class,CartProducts::class,'cart_id','id' )->withPivot('cart_products');
}
and this is my cart_products table
Schema::create('cart_products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedInteger('product_id')
->references('id')->on('products')->onDelete('cascade');
$table->unsignedInteger('cart_id')
->references('id')->on('carts')->onDelete('cascade');
$table->unsignedInteger('quantity');
$table->timestamps();
});
i got all products finally , but i need to get quantity column with that realtion
any help?
Use the many to many relation with belongsToMany()
public function products()
{
return $this->belongsToMany(Product::class)->withPivot('quantity')->withTimestamps();
}
You may retrieve the qauantity column from the cart_products pivot table by passing the column name to the withPivot method
//...
return $this->belongsToMany('App\Product')
->using('App\CartProducts')
->withPivot('quantity');
See
Defining Custom Intermediate Table Models
in Docs
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.
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();
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 :)
I am trying to understand what I am missing here.
Apps migration
Schema::create('apps', function (Blueprint $table) {
$table->increments('id');
$table->integer('show_id')->unsigned()->index();
$table->string('name');
$table->integer('provider_id')->unsigned()->index();
$table->timestamps();
});
Show migration
Schema::create('shows', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
So I create an apps model that has the following function
public function Show() {
return $this->hasOne(Show::class);
}
But in php artisan tinker when I do $app->Show; I get the following error:
Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1 no such column: shows.app_id (SQL: select * from "shows" where "shows"."app_id" = 1 and "shows"."app_id" is not null limit 1)'
Am I mis-understanding the relationships?
Your relation should be as:
Apps model:
public function show() {
return $this->hasOne(Show::class, 'id', 'show_id');
}
Or it can be:
public function show() {
return $this->belongsTo(Show::class);
}
Docs
You do not have an app_id in your shows migration.
edit: Taking from the Laravel Docs and changing it to fit your situation
Eloquent determines the foreign key of the relationship based on the model name. In this case, the show model is automatically assumed to have a app_id foreign key.
A one-to-one relationship consists of a hasOne and a belongsTo. The table that contains the foreign key field must be on the belongsTo side of the relationship.
Since your apps table contains the show_id field, it is stated that apps belong to shows, and shows has one (or many) apps.
Given this, you need to change your Show relationship on your Apps model to use the belongsTo relationship.
public function Show() {
return $this->belongsTo(Show::class, 'show_id');
}
Unless you rename your relationship method so that it is lowercase (function show()), the second parameter is required. If you renamed the relationship, Laravel could build the proper key name and you could leave off the second parameter:
public function show() {
// For belongsTo, second parameter defaults to {function_name}_id.
return $this->belongsTo(Show::class);
}
In your apps model :
public function Show() {
return $this->belongsTo('yourmodelnamespace\Show','id','show_id');
}
And you need create Show model too ..
Hope it will works~~
You can use relation like this
public function Show() {
return $this->hasOne(Show::class, 'id','id');
}
I have a User and a Quiz models. I have many-to-many relationship defined between them in the following way:
User model
public function subscriptions()
{
return $this->belongsToMany(Quiz::class, 'subs_users', 'user_id', 'quiz_id')->withTimestamps()->withPivot('accepted');
}
Quiz model
public function subscribers()
{
return $this->belongsToMany(User::class);
}
Pivot table
Schema::create('subs_users', function (Blueprint $table) {
$table->integer('user_id')->unsigned();
$table->integer('quiz_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('quiz_id')->references('id')->on('quizzes')->onDelete('cascade');
$table->primary(['user_id', 'quiz_id']);
$table->boolean('accepted')->index();
$table->timestamps();
});
When I call $quiz->subscribers, it returns a collection of users as expected. However, $user->subscriptions always returns an empty array. Why is that?
Edit
It seems, that replacing this line in Quiz
return $this->belongsToMany(User::class);
with
return $this->belongsToMany(User::class, 'subs_users', 'quiz_id', 'user_id')->withTimestamps()->withPivot('accepted');
Solves the issue, but I still can't understand why the first variant does not work.
Look at this:
public function subscriptions()
{
return $this->belongsToMany(Quiz::class, 'subs_users', 'user_id', 'quiz_id')->withTimestamps()->withPivot('accepted');
}
You mixed the foreign key with other key: user_id and quiz_id.
Remember when doing many to many relation that: first of foreign key's declared in belongsToMany is a key related to the current model.
Replacing belongsToMany() relationship in Quiz model with following:
return $this->belongsToMany(User::class, 'subs_users');
Solves the issue. It seems, that when a non-standard name is used for the pivot table, both sides must explicitly state it. In other words, 'subs_user' pivot table name must be present in belongsToMany() relationship declarations in both models.