I have table called invoices, orders, games, products, users
This is my invoices table structure
id name order_id
This is my orders table structure
id name game_id product_id user_id
This is my games table structure
id name display_name
This is my products table structure
id product_sku name price profit
As you see in this case I'm trying to make an order that generate an invoices after you place an order. In the invoices, I wanted to show the games name, products name, price, and user who make the order.
What relationship should I use? is it hasMany, or belongsToMany? or should I make another table called invoice_order?
Updated!
I forgot to show my table game_product, I already make a belongsToMany relationship between games and products table.
id game_id product_id
Cmiiw
I think you should have the following table structure:
Orders (renamed from invoice)
id name user_id
order_product (pivot)
order_id product_id
games
id name display_name
products
id product_sku name price profit game_id
These should be the relationships:
Order model
public function products() {
return $this->belongsToMany(Product::class);
}
public function user() {
return $this->belongsTo(User::class);
}
Game model
public function product() {
return $this->hasMany(Product::class);
}
public function orders() {
return $this->hasManyThrough(Order::class, Product::class);
}
Product model
public function game() {
return $this->belongsTo(Game::class);
}
public function orders() {
return $this->belongsToMany(Order::class);
}
This way you can generate an invoice:
$invoiceData = Order::with([ 'user', 'products', 'products.game' ])->find($id);
This will have all necessary information of the order within the $invoiceData object e.g. $invoiceData->user will be the user placing the order and $invoiceData->products will be a collection of ordered products.
Note that it's usually good practice to put the price in the order_product pivot as an extra pivot field since the price people buy an item for is not always the price that the item goes for at all times so that way you can have information on the price the item was sold for rather than what item was sold and how much it costs today.
A simple belongs to relation is good enough for your case scenario
Invoice.php
public function order(){
return $this->belongsTo(Order::class);
}
Order.php
public function game(){
return $this->belongsTo(Game::class)->select('id', 'name')
}
public function product(){
return $this->belongsTo(Product::class)->select('id', 'name')
}
Controller.php
Invoice::with(['order' => function($q) {
return $q->with('game', 'product');
})->get();
Related
I need to select only some columns from specifics morph models.
The withdrawal model:
public function product()
{
return $this->morphTo('product', 'product_type', 'product_id');
}
The Product1, Product2, and Product3 models has an ID and a name column. The Product4 and Product5 does not have the name column, so when I use the next code ->with('product:id,name') it give me the error SQLSTATE[42S22]: Column not found
¿How can I select some specific column from specific models?
You may add a scope to the product models.
public function scopeFilter($query)
{
return $query->select(['id', 'name', 'slug']);
}
Replace the array with your columns.
Then, in your withdrawal model, add the scope to the product relationship. Please make sure you have added the scope to all the potential product models.
public function product()
{
return $this->morphTo('product', 'product_type', 'product_id')->filter();
}
I want the details of product that are added to wishlist table. I'm getting the data from wishlist table but i want to establish relation from product and user model also so that i can get the details of the product. My table Structure is :
Wishlists table:
id | product_id | user_id
products table :
id | name | price
users table :
id | first_name | last_name | contact
Wishlist Model :
public function user(){
return $this->belongsTo(User::class);
}
public function product(){
return $this->belongsTo(Product::class);
}
Product Model :
public function wishlist(){
return $this->hasMany(Wishlist::class);
}
public function users()
{
return $this->belongsToMany(User::class);
}
Users Model :
public function wishlist(){
return $this->hasMany(Wishlist::class);
}
I'm getting data from wishlist table through this code but can't get data from product table :
return Wishlist::with('product')->where('user_id', auth()->id())->get();
product relation is returning null
I think it's better to use a Many To Many relationship. In this case, you don't need the Wishlist model.
Product.php
public function users()
{
return $this->belongsToMany(User::class,'wishlists');
}
User.php
public function products()
{
return $this->belongsToMany(Product::class, 'wishlists');
}
Then you can get the user's wishlist like this:
auth()->user()->products;
I have the following structure:
orders
id
name
products
id
name
items
id
order_id
product_id
quantity
The relationships are as follows:
Order
public function items(){
return $this->hasMany(Item::class)
}
public function products(){
return $this->hasManyThrough(Product::class, Item::class);
}
Item
public function order(){
return $this->belongsTo(Order::class);
}
public function product(){
return $this->belongsTo(Product::class);
}
Product
public function items(){
return $this->hasMany(Item::class);
}
I wish to get all products for the order doing something like this:
$order->items()->products()->get() using the hasManyThrough method, but I must be doing it wrong since it tries to look for item_id in the products table.
I realized that I do not need many through, I just need to use items table as a pivot table, defining the relationship on the Order model just like this:
public function products(){
return $this->belongsToMany(Product::class, 'items');
}
plans
id
name
posts
id
title
users
id
name
categories
id
name
plan_post //BelongsToMany
plan_id
post_id
plan_user //BelongsToMany
id
plan_id
user_id
I need to relate a category to the pan_user record ...
plan_user_category // what ???
plan_user_id
category_id
There can be no such relationship. If you have a pivot table, it binds two tables that are not pivot.
What is a pivot table? This is a table that has no increments. And it binds to the increments of tables for which it is a pivot. If the table has increments then it does not automatically pivot.
plan_user_category // what ???
plan_user_id // BelongsTo or BelongsToMany -> plan_user
category_id // BelongsTo or BelongsToMany -> categories
If I understand you correctly, you want to have a plan - user - category relationships.
If so, make the following tables:
plans (id, ...)
users_plans (user_id, plan_id)
users (id, ...)
users_categories (user_id, category_id)
categories (id, ...)
and that from plans to get to categories it is necessary to build relationships through models
class Plans
public function users()
{
return $this->belongsToMany('App\User', 'users_plans', 'user_id', 'plan_id');
}
class User
public function categories()
{
return $this->belongsToMany('App\Category', 'users_catogories', 'category_id', 'user_id');
}
foreach($plans->users() as $user) {
$categories[] = $user->categories();
}
I have to tables to save orders and order_details
orders
id
name
order_details
id
name
quantity
price
order_id
This is how I get total price
Transaction.php
public function details()
{
return $this->hasMany('Detail');
}
public function getTotalPriceAttribute()
{
return $this->details()->sum(DB::raw('quantity * price));
}
Is there any way more elegant?