get extra column with eloquent hasManyThrough - laravel

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

Related

How to add many to many extra pivot columns?

I have two tables products and orders which are linked by a pivot table order_product with the id of each table. But I also want to add an amout column to the pivot table. How can I do this with laravel Voyager?
Easily just define it in your migration file of order_product and access it from relation function as bellow:
Schema::create('order_product', function (Blueprint $table) {
$table->unsignedBigInteger('order_id');
$table->unsignedBigInteger('product_id');
$table->unsignedInteger('amount');
});
and for example in your product model:
public function orders()
{
return $this->belongsToMany(Order::class)
->withPivot('amount');
}

Relationship not working and looking for a strange table name?

I have created a migration for a lookup table with a many to many relationship.
Schema::create('user_partner__organization', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('partner_organization_id');
$table->foreign('user_id')
->references('id')
->on('users');
$table->foreign('partner_organization_id')
->references('id')
->on('partner_organizations');
});
}
Then I am setting up the relationships to be able to go through the user_partner__organization table
In UserPartnerOrganization model
public function partnerOrganizations()
{
return $this->hasMany(PartnerOrganization::class);
}
And in PartnerOrganization
public function userPartnerOrganizations()
{
return $this->belongsToMany(UserPartnerOrganization::class);
}
And finally I am trying to go through the relationship to get a user_id when I know the partner_organization_id which I have in the $organization
$test = $organization
->partnerOrganization()
->first()
->userPartnerOrganizations()
->first();
The partnerOrganization relationship is working nicely but when I try to implement the userPartnerOrganizations I get this error in my log file
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'homestead.partner_organization_user_partner_organization' doesn't exist in /home/vagrant/api/vendor/laravel/framework/src/Illuminate/Database/Connection.php:359
Don't understand where this strange table name is coming from or why the relationship is not working.
since your not following Laravel convention in tables name, you have to provide the pivot table name in relation declaration:
public function partnerOrganizations()
{
return $this->belongsToMany(PartnerOrganization::class,'user_partner__organization','user_id','partner_organization_id');
}
public function userPartnerOrganizations()
{
return $this->belongsToMany(UserPartnerOrganization::class,'user_partner__organization','partner_organization_id','user_id');
}
also note that the relation from both side should be belongsToMany
more about many to many relation in Laravel doc.

laravel hasMany polymorphic relationship in where clause

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

How to use relationship in laravel?

I use work with relationship in laravel 5.6.
I create product table with migration:
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('slug');
$table->text('description');
$table->string('tags');
$table->string('original_price');
$table->integer('view_order')->default(0);
$table->unsignedInteger('admin_id');
$table->foreign('admin_id')->references('id')->on('admins');
$table->boolean('status');
$table->timestamps();
});
And i create category table with migration:
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->boolean('status');
$table->timestamps();
});
And create product_categories table with migration:
Schema::create('product_categories', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('product_id');
$table->foreign('product_id')->references('id')->on('products');
$table->unsignedInteger('category_id');
$table->foreign('category_id')->references('id')->on('categories');
$table->timestamps();
});
Now, I use Bootstrap Multiselect for categories in one product.
In category model:
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function products()
{
return $this->belongsToMany(Product::class);
}
In Product model:
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function categories()
{
return $this->belongsToMany(Category::class);
}
How to add category_id and product_id in product_categories table with relationship?
Check the documantation related to Many to many Relationships.
Your pivot table doesn't follow Laravel's convention, either update your table name or update your relationships to address this issue.
The convention is the alphabetical order of the two models, thus your pivot table should be named: category_product
If you do not want to update the table name, update your relationships.
public function categories()
{
return $this->belongsToMany(Product::class, 'product_categories')
}
public function products()
{
return $this->belongsToMany(Category::class, 'product_categories')
}
Now to "save an entry to the pivot table" -or in other words: to create the relationship between the two models- you may use attach or sync method.
$product->categories()->attach($category);
$product->categories()->attach([$categoryId1, $categoryId2]);
sync is different.
The sync method accepts an array of IDs to place on the intermediate table. Any IDs that are not in the given array will be removed from the intermediate table.
To detach (delete entry in pivot table), simple use the detach method.
$product->categories()->detach([1, 2]);
Of course, do the same for Category.
Your model names are Product and Category and the derived relational table will be category_product because category came before product in alphabetical order.
You only have to add the pivot table:
public function categories()
{
return $this->belongsToMany(Product::class, 'product_categories')
}
public function products()
{
return $this->belongsToMany(Category::class, 'product_categories')
}
Now for save with relationship:
$product->categories()->attach($category);
$product->categories()->attach([$category_id_1, $category_id_2]);
You only have to add the pivot table:
public function products()
{
return $this->belongsToMany(Product::class, 'product_categories');
}
public function categories()
{
return $this->belongsToMany(Category::class, 'product_categories');
}
By default, laravel derives the table name from the alphabetical order of the related model names. Here your model names are Product and Category and the derived relational table will be category_product because category came before product in alphabetical order. Either you can change the table name or you can override this my mentioning the table name as the second parameter in the relational method as follows.
public function products()
{
return $this->belongsToMany(Product::class, 'product_categories');
}
public function categories()
{
return $this->belongsToMany(Category::class, 'product_categories');
}

Eloquent Relationships Not Working as Expected

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

Resources