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?
Related
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();
I have 3 tables
auctions [id, winner_user_id, title]
bids [id, auction_id, amount, user_id]
users [id, name]
relations
Auction
...
public function winningBidder(){
return $this->belongsTo('User', 'winner_user_id', 'id');
}
public function bids(){
return $this->hasMany('Bid');
}
User
...
public function bids(){
return $this->hasMany('Bid');
}
Bid
...
public function auction(){
return $this->belongsTo('Auction');
}
public function user(){
return $this->belongsTo('User');
}
What i am trying to do is the highest bid for the winner
eager load
$auctions = Auction::with('winningBidder.bids')->get();
loads all bids instead of bids of that auction and adding max(amount) to about will give max of all
is it possible to get highest bid of winning user for each auction?
If you want to eager load the winningBidders and the winningBid with each auction you could do the following:
In your Auction model add a new one-to-one relationship for the highest / winning bid:
public function winningBid()
{
return $this->hasOne('Bid')->max('amount');
}
Then you can do the following:
$auctions = Auction::with(['winningBidder', 'winningBid'])->get();
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');
}
I have 3 table on my database :
table 1 = user (hasMany order)
table 2 = order (hasMany order_detail, belongsTo user)
table 3 = order_detail (belongsTo order)
On my order_detail model i add this function :
public function order() {
return $this->belongsTo('App\Order');
}
so i can call the order data without define it from controller, i just define order_detail on my controller
$order_detail->order->invoice_number
but how to call the user data from the order detail?
I try use this
$order_detail->order->user
but it didn't work for me..
Is there any idea to call the grand parent relation?
In order model add function for order_detail:
public function order_details() {
return $this->hasMany('order_detail');
}
and for user:
public function user() {
return $this->belongsTo('user');
}
In user model add:
public function orders() {
return $this->hasMany('order');
}
Then, you can call in the controller:
$details = Order::find(1)->order_details->where('order_detail_id', 5)->first();
$userName = $details->username;
// ^
// column name in order_detail table
More info in the docs.
I think this is the more complete way to define the relationships:
// User model
public function orders(){
// I'm telling that users has many order. The orders have an user_id field that match with the ID field of the user.
return $this->hasMany('App/Order', 'user_id' , 'id');
}
// Order model
public function order_details(){
// I'm telling that order has many order_details. The order_details have an order_id field that match with the ID field of the order.
return $this->hasMany('App/OrderDetail', 'order_id' , 'id');
}
public function user(){
// I'm telling that an order belongs to an user. The user has an ID field that match with the order_id field of the order.
return $this->belongTo('App/User', 'id', 'user_id');
}
// OrderDetail Model
public function order(){
// I'm telling that an order detail belongs to an order. The order has an ID field that match with the order_id field of the order detail.
return $this->belongTo('App/Order', 'id', 'order_id');
}
I have seen that you put just the model name as first parameter in your relation definition. I think you must put the relative path from the root to the Model. In my case, I have the models as childs of the App folder.