Laravel eloquent don't get relation model many to many relation - laravel

[][1]we can retrieve the Post model for a Comment by accessing the post "dynamic property
I have a Posts table
My Order Model
class Order extends Model
{
protected $table = 'orders';
protected $fillable = ['user_id', 'billing_phone', 'billing_address',
'payment_method', 'payment_status', 'product_id', 'order_status'];
}
public function products()
{
return $this->belongsToMany(Product::class, 'order_product', 'order_id', 'product_id');
}
}
My web route
Route::get('get-orders', function() {
$orders = \App\Models\Order::all();
foreach ($orders as $order) {
foreach ($order->products as $product) {
echo 'ID: ' . $product->name;
}
}
});
Now I want to get orders & its products, what is the problem?
When i due and dump this is the retun result
[1]: https://i.stack.imgur.com/IaqEv.png

Try this with better performance.
Order.php model:
class Order extends Model
{
protected $table = 'orders';
protected $fillable = [
'user_id',
'billing_phone',
'billing_address',
'payment_method',
'payment_status',
'product_id',
'order_status'
];
public function products()
{
return $this->belongsToMany(
Product::class,
'order_product',
'order_id',
'product_id'
);
}
}
web.php route file:
Route::get('get-orders', function() {
//use eager load here, better performance.
$orders = \App\Models\Order::with('products')->get();
foreach ($orders as $order) {
foreach ($order->products as $product) {
echo 'ID: ' . $product->name;
}
}
});

Related

Favorite functionality for my laravel application

I'm currently trying to make a favorite functionality to my laravel application. I'm trying to access the post table with eloquent, but it says property posts(the function in the favorite model) does not exist.
Update: I updated the query. If I dump $favorite I get two items, which is correct, but now I get this error message instead:Property [posts] does not exist on the Eloquent builder instance. (View: C:\xampp\laravelprojects\Skakahand\resources\views\profile\index.blade.php)
<div class="favorite-section">
<p>Mina favoriter</p>
{{$favorite->posts->title}}
</div>
This is my controller:
public function index(User $user)
{
$favorite = Favorite::where('user_id', auth()->user()->id)
->get();
return view('profile.index',[
'user' => $user,
'favorite' => $favorite
]);
}
Favorite model:
class Favorite extends Model
{
use HasFactory;
protected $fillable = [
'user_id'
];
public function users()
{
return $this->belongsTo(User::class);
}
public function posts()
{
return $this->belongsTo(Post::class);
}
}
and post model:
class Post extends Model
{
use HasFactory;
/* use Sluggable; */
protected $fillable = [
'title',
'body',
'category',
'decision',
'number',
'place',
'image_path',
'slug',
'price',
'user_id',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function favorites(){
return $this->hasMany(Favorite::class);
}
}
First correct Model like this
class Favorite extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'post_id',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function post()
{
return $this->belongsTo(Post::class);
}
}
In controller change code like this for for avoid lazy loads
public function index(User $user)
{
$favorites = Favorite::where('user_id', auth()->user()->id)
->with('post')
->get();
return view('profile.index',[
'user' => $user,
'favorites' => $favorites
]);
}
in blade use code like
<div class="favorite-section">
<p>Mina favoriter</p>
<ul>
#foreach($favorites as $favorite)
<li>{{ $favorite->post->title ?? '' }} </li>
#endforeach
</ul>
</div>
just include ->with() for relationship,
your query should look like this
$favorite = Favorite::where('user_id', auth()->user()->id)->with('post')
->get();
return view('profile.index',compact('favorite','user'));

How to count and sum inner relational model in laravel

I am building a small application in Laravel where I got stuck with the sum of inner relational data,
I have a model Company which has Many relation associatedProjects and associatedProjects belongs to relation project and project hasOne technicalDescription.
Company Model:
class Company extends Model {
public function roles()
{
return $this->belongsToMany('Noetic\Plugins\Conxn\Models\Variables\Company\Role', 'company_role_relation', 'company_id', 'role_id')->withTimestamps();
}
public function specialisations()
{
return $this->belongsToMany('Noetic\Plugins\Conxn\Models\Variables\Company\Role', 'company_specialisation_relation', 'company_id', 'specialisation_id')->withTimestamps();
}
public function associatedProjects()
{
return $this->hasMany('Noetic\Plugins\Conxn\Models\Project\AssociateCompany','company_id','id');
}
}
AssociateCompany Model:
class AssociateCompany extends Model {
protected $table = 'project_associate_company';
protected $fillable = [
'project_id', 'company_role_id', 'company_specialisation_id', 'company_id', 'link', 'file_name'
];
public function project()
{
return $this->belongsTo('Noetic\Plugins\Conxn\Models\Project','project_id','id');
}
public function company()
{
return $this->belongsTo('Noetic\Plugins\Conxn\Models\Company','company_id','id');
}
public function companyRole()
{
return $this->belongsTo('Noetic\Plugins\Conxn\Models\Variables\Company\Role',
'company_role_id','id');
}
public function specialisation()
{
return $this->belongsTo('Noetic\Plugins\Conxn\Models\Variables\Company\Role',
'company_specialisation_id','id');
}
}
Project Model
class Project extends Model {
protected $fillable = [
'user_id','koshy_id', 'name', 'slug', 'owner_spv', 'spv_link', 'latitude', 'longitude',
'landmark', 'city', 'district', 'state', 'pin_code', 'region_id', 'country', 'building_use',
'sector', 'conxn_id', 'parent_project_id', 'website', 'project_logo', 'tracked', 'verified',
'code_link', 'status', 'active', 'premium','area'
];
public function technicalDescription()
{
return $this->hasOne('Noetic\Plugins\Conxn\Models\Project\TechnicalDescription','project_id','id');
}
public function associateCompany()
{
return $this->hasMany('Noetic\Plugins\Conxn\Models\Project\AssociateCompany','project_id','id');
}
}
Now this technicalDescription has fields construction_cost, now I want to first count total number of associatedProject and fetch sum of all the project's construction_cost which is in technicalDescription, some what I have done this code:
$company = Company:: where( 'status', 'saved')
->withCount( 'associatedProjects' )
->with('associatedProjects.project.technicalDescription')
->get()
->transform(function ($value) {
$value['project_value'] = $value['associatedProjects']->flatten(2)
->pluck('project.technicalDescription')->sum('construction_cost');
return $value;
})
->sortByDesc('project_value')
->forpage( $request->page , 10 );
$next = $request->page+1 ;
$previous =$request->page-1 ? abs($request->page-1):1 ;
I am unable to use paginate over here as laravel collection doesn't have such method, moreover the query logic also doesn't appear accurate.
Any suggestions are welcome. Thanks
You can use a BelongsToMany relationship to get the technicalDescriptions directly:
class Company extends Model {
public function technicalDescriptions() {
return $this->belongsToMany(
'Noetic\Plugins\Conxn\Models\Project\TechnicalDescription',
'project_associate_company',
'company_id',
'project_id',
null,
'project_id'
);
}
}
$company = Company::where('status', 'saved')
->withCount(['technicalDescriptions as project_value' => function($query) {
$query->select(DB::raw('sum(construction_cost)'));
}])
->orderByDesc('project_value')
->paginate();

How can I solve "Relation 'a' is not instance of HasOne or BelongsTo." in the laravel?

My laravel eloquent like this :
$query = ItemDetail::selectRaw('a.item_number, sum(abs(a.quantity)) as "total_quantity"')
->from('item_detail as a')
->join('items as b', 'b.id', '=', 'a.item_number');
if(isset($param['vendor'])) {
$query = $query->where('b.vendor_id', '=', $param['vendor']);
}
$query = $query->groupBy('a.item_number')
->paginate($paged);
return $query;
If the query executed, there exist error like this :
Relation 'a' is not instance of HasOne or BelongsTo.
How can I solve this problem?
Update
My item model like this :
class Item extends Model
{
...
protected $fillable = [
'name',
'vendor_id'
];
public function item_details()
{
return $this->hasMany(ItemDetail::class, 'id', 'item_number');
}
}
My item detail model like this :
class ItemDetail extends Model
{
....
protected $fillable = [
'item_number',
'name',
'posting_date'
];
public function item()
{
return $this->belongsTo(Item::class, 'id', 'item_number');
}
}
According to your few details, please confirm if this is what you want:
Item Model:
class Item extends Model
{
...
protected $fillable = [
'name',
'vendor_id'
];
public function item_details()
{
return $this->hasMany(ItemDetail::class, 'item_number', 'id');
}
}
ItemDetail Model:
class ItemDetail extends Model
{
....
protected $fillable = [
'item_number',
'name',
'posting_date'
];
public function item()
{
return $this->belongsTo(Item::class, 'item_number', 'id');
}
}
Controller Method:
$itemDetails = ItemDetail::whereHas('item', function($q) use ($param) {
if (isset($param['vendor']){
$q->where('vendor_id', '=', $param['vendor']);
}
})
->selectRaw('item.id', 'item_detail.item_number', 'sum(abs(a.quantity)) as total_quantity')
->groupBy('item_number')->paginate($paged);
View file:
#foreach($itemDetails as $itemDetail)
#dump($itemDetail->item_number)
#dump($itemDetail->total_quantity)
#endforeach
It makes more sense to access the main model you want and include in it, the relationships you need to include.
Here's a potential different solution:
$query = Item::with(['item_details' => function ($query) {
$query->groupBy('item_number')->selectRaw("item_number, sum(abs(a.quantity)) as 'total_quantity'");
}]);
if (isset($param['vendor'])) {
$query->where('vendor_id', $param['vendor']);
}
$itemsPage = $query->paginate($paged);
return $pages;
You can access the paged data if you do:
foreach ($itemsPage as $item) {
// $item is an instance of Item
// $item->item_details->total_quantity should have the sum of the item details
}
I can only guess because of too few information: your model is missing something like this:
public function a()
{
return $this->belongsTo(RelatedModel::class);
}

How can I add, delete and get a favorite from product with polymorphic relationship, in Laravel 5.6?

My product model like this :
<?php
...
class Product extends Model
{
...
protected $fillable = ['name','photo','description',...];
public function favorites(){
return $this->morphMany(Favorite::class, 'favoritable');
}
}
My favorite model like this :
<?php
...
class Favorite extends Model
{
...
protected $fillable = ['user_id', 'favoritable_id', 'favoritable_type'];
public function favoritable()
{
return $this->morphTo();
}
}
My eloquent query laravel to add, delete and get like this :
public function addWishlist($product_id)
{
$result = Favorite::create([
'user_id' => auth()->user()->id,
'favoritable_id' => $product_id,
'favoritable_type' => 'App\Models\Product',
'created_at' => Carbon::now()
]);
return $result;
}
public function deleteWishlist($product_id)
{
$result = Favorite::where('user_id', auth()->user()->id)
->where('favoritable_id', $product_id)
->delete();
return $result;
}
public function getWishlist($product_id)
{
$result = Favorite::where('user_id', auth()->user()->id)
->where('favoritable_id', $product_id)
->get();
return $result;
}
From the code above, I'm using parameter product_id to add, delete and get data favorite
What I want to ask here is : Whether the above is the correct way to add, delete and get data using polymorphic relationship?
Or is there a better way to do that?

Laravel 5.5 Relationships

I'm trying to implement relationships between models and i recieve "Trying to get property 'products' of non-object" and i don't understand why, because i used this before in the same way and it's worked fine.
The logic of relationship is that 1 Merchant hasMany Products
this is the code that i'm using:
Merchant Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Merchant extends Model {
protected $table = "merchants";
protected $fillable = [
'merchant_id', 'merchant_name', 'secret_key', 'merchant_address', 'merchant_phone', 'merchant_admin',
'merchant_contact', 'merchant_mail', 'merchant_description', 'enable', 'created_at', 'updated_at'];
public function users() {
//many to many
return $this->belongsToMany('App\User');
}
public function branchOffices() {
return $this->hasMany('App\BranchOffice', 'merchant_id', 'merchant_id');
}
public function products() {
return $this->hasMany('App\Products', 'merchant_id', 'merchant_id');
}
public function transactions() {
return $this->hasMany('App\Transaction', 'merchant_id', 'merchant_id');
}
public function readers() {
return $this->hasMany('App\Reader', 'merchant_id', 'merchant_id');
}
}
Product Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model {
protected $table = "products";
protected $fillable = [
'id', 'barcode', 'description', 'price', 'currency_id', 'merchant_id', 'branch_id',
'enable', 'created_at', 'updated_at'];
public function merchants() {
return $this->belongsTo('App\Merchant', 'merchant_id', 'merchant_id');
}
public function currencies() {
return $this->belongsTo('App\Currency', 'iso_4712', 'currency_id');
}
public function branch_sectors() {
return $this->belongsToMany('App\BranchSector');
}
}
And this is the method in ProductController:
public function merchantProducts() {
$products = Merchant::find('merchant_id')->products;
return $products;
}
If someone can help me i'll be very thankfull.
Thanks in advance!!
Assume merchant is not guaranteed existing in database giving merchant id, it is better off to check if merchant exists, and retrieves its products if so.
$products = collect();
$merchant = Merchant::find($merchant_id);
if($merchant) {
$products = $merchant->products;
}
return $products;
all!!
Finally i solved this problem using resources in this way:
public function merchantProducts(Request $request) {
$merchant_id = $request->merchant_id;
$products = Product::where('merchant_id', $merchant_id)->paginate(15);
return ProductResource::collection($products);
}
Thanks to all!!

Resources