laravel model relationship 5.5 - laravel

1. users
1. id
2. name
2. categories
1. id
2. category_name
3. user_id
3. posts
1. id
2. post_title
3. category_id
So now I want to show data in my view
like : post_title->category_name->user_name
How to do in laravel query relationship in model

Define the relationships
class Post extends Model
{
return $this->blongsTo(Category::class);
}
class Category extends Model
{
return $this->blongsTo(User::class);
}
Now
$post = with('category.user')->whereId(1)->first(); //1 is my guess
$post->category()->user->name();
Also it seems like a has-many-through relationship though you can access a user's post like this
$user->posts;
For that you need to define:
class User extends Model
{
/**
* Get all of the posts for the user.
*/
public function posts()
{
return $this->hasManyThrough(Post:class, Category::class);
}
}

$Query=DB::select('select posts.post_title,categories.category_name,
users.name from posts,categories,users where users.id=categories.user_id and
categories.id=posts.category_id');
if you dont use DB::
you can use your model
$Query = Users::select('users.name', 'posts.post_title', 'categories.category_name')
->join('categories', function ($join) {
$join->on('categories.user_id', '=', 'users.id')
->join('categories.id', '=', 'posts.category_id');
})
->get();
check spell table name and columns
but if there is duplicate in data it wont work

Related

Laravel apply where clause to belongsToMany query using with() method

I have a products table with brand_id, and a category_products table with, product_id and category_id.
My Products model :
class Product extends Model
{
public function categories() {
return $this->belongsToMany(Category::class)->withTimestamps();
}
}
My Brands Model :
class Brand extends Model
{
public function products() {
return $this->hasMany(Product::class)->with(['categories']);
}
}
My question is, How can I fetch the products from a Brand instance that belongs to certain category?
$brand = App\Brand::find(1);
/*
I want to be able to do something in the likes of :
*/
$brand->products_which_are_under_this_category
Remove with(['categories']) method from inside products() and write a query like that.
$brand->products()->with(['categories' => function ($query) {
$query->where('category_id', CATEGORY_ID);
}])->get();
hope this can help.

Using withCount and Distinct with Laravel

I would like to create a withCount subquery for this model.
Thanks to Iqbal Butt
I have this snippet for getting the count.
$count = Action::select('article_id as assigned');
if (!empty($action_type_id))
{
$count = $count->where('action_type_id', $action_type_id);
}
if (!empty($set_id))
{
$count = $count->where('set_id', $set_id);
}
$count = $count->distinct('article_id')->count('article_id');
I would like to execute it like this, but I feel this is painfully flawed.
Clarification edit
I have a many to many relationship of sets to articles.
Each article has a number of actions.
The actions can have a variety of action types.
I need to count the types of actions for each article in a given set.
$sets = Set::withCount(['actions' => function ($q) use ($action_type_id, $set_id) {
$q->select('article_id as assigned');
if (!empty($action_type_id))
{
$q->where('action_type_id', $action_type_id);
}
if (!empty($set_id))
{
$q->where('set_id', $set_id);
}
$q->distinct('article_id')
->count('article_id');
// I believe this is executing inner query
}])
->get();
return $sets;
This gives me the error, more then likely because the inner query is executing and without the outer query.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sets.id' in
'where clause' (SQL: select count(distinct article_id) as aggregate
from actions where sets.id = actions.set_id and
action_type_id = 1 and set_id = 1)
Edit per comments
Article Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
/**
* Get the sets for the article.
*/
public function sets()
{
return $this->belongsToMany(Set::class);
}
public function actions()
{
return $this->hasMany(Action::class);
}
}
Set Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Set extends Model
{
/**
* Get the articles for the set.
*/
public function articles()
{
return $this->belongsToMany(Article::class);
}
public function actions()
{
return $this->hasMany(Action::class);
}
}
Action Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Action extends Model
{
/**
* Get the set that owns the action.
*/
public function set()
{
return $this->belongsTo(Set::class);
}
/**
* Get the article that owns the action.
*/
public function article()
{
return $this->belongsTo(Article::class);
}
}
Database
actions
id
set_id
article_id
action_type_id
sets
id
name
articles
id
name
article_set
id
set_id
article_id
Here is something that will get the data you need although it uses the returned collection to calculate the count.
$articles = Set::find($set_id)
->articles()
->with('actions')
->get()
->map(function($article){
$article->action_type_count = $article->actions->unique('action_type')->count();
return $article;
});
This will give you a collection of articles. The action type count is in a property action_type_count on each article in the collection. So to get the first article's action type count:
$articles->first()->action_type_count;

Reverse ordering Laravel eloquent eager loaded collection

I have a collection of products for a particular order like this ->
$products = $order->products()->with('store.seller')->get();
What I want to get is a $sellersCollection where,
each $seller has $stores
each $store has $products
[$seller - stores - products]
How can it be done efficiently without making another db call.
using eloquent relationship you can access this.use appropriate relationship hasOne() or hasMany() in your model.Ex. Seller->hasOne(store) and store->belongsTo(seller) like that.
Doing with eloquent way you could get the desired results as
$sellers = Seller::with('stores.products')->get();
Above will return you all sellers with their related stores and each store with their related products
class Seller extends Model{
public function stores(){
return $this->hasMany('App\Store', 'seller_id')
}
}
class Store extends Model{
public function products(){
return $this->hasMany('App\Product', 'product_id')
}
}
I believe order and products are related as m:m via pivot table so you could define their relation as belongsToMany
class Product extends Model{
public function orders(){
return $this->belongsToMany('App\Order')
}
}
Edit I want the particular $sellers who are associated with the order just made and with all the info of the products buyer ordered like quantity
$sellers = Seller::with(['stores.products.orders' => function ($query) use ($orderId) {
$query->where('id', '=', $orderId);
}])
->whereHas('stores.products.orders', function ($query) use ($orderId) {
$query->where('id', '=', $orderId);
})
->get();

getting pivot columns in collection in laravel

how to return collection of eloquent models with pivot column? For example, there are M:N relationship between users and vats. I want to retrieve all users data( with vats and with pivot column (costOfDelivery) , which is in pivot table user_vat).
In my code I have:
$vats = Vat::whereHas('users', function($query) use ($user) {
$query->where('user_id', $user->id);
})->with('country')
->get();
but this return data from vats and country, not from pivot table "user_vat", how to retrieve also costOfDelivery?
To retrieve the data from pivot table, you must use pivot attribute
Something like this
foreach($users->roles as $role){
echo $role->pivot->created_at;
}
To return json, you can use the toJson() method like
$vat->toJson();
<?php
/**
* The model class with the belongsToMany user class relation.
*/
class Vat extends Model
{
public function user()
{
return $this->belongsToMany(\App\User::class)
->withPivot(['cost_of_delivery', /**Specific columns for the pivot.*/]);
}
}
<?php
/*
* Your query (which I think is a little bit complicated that it should be.
*/
$vats = Vat::whereHas('users', function($query) use ($user) {
$query->where('user_id', $user->id);
})->with(['country', 'users'])
->get();
I would use sth. like:
<?php
$user->load(['vats.country']);
$vats = $user->getRelationValue('vats');
And
$vats->first()->pivot->cost_of_delivery
should give you the cost of delivery of the first vat.

Laravel 4 eloquent

Is there any way I can do this with eloquent?
$orders = Customer::with('orders','orders.shop')->where('orders.shop.location','=','Japan')->get()
Customers, orders and shop are tables where 1 customer has many orders and each order has one shop only.
Location is a column in the shop table
I keep getting an error stating orders.shop.location is a column not found.
Anyone can help? Thanks in advance.
You need to defined relationship in your model classes.
Customer model:
public function orders()
{
return $this->hasMany('Order');
}
Order model:
public function customer()
{
return $this->belongsTo('Customer');
}
Then if you want orders of a special customer you just have to do :
$orders = Customer::find($id)->orders;
Or find the user attatched to an order:
$user = Order::find($id)->user;
You can also use the same kind of relation between your Shop and Order model and do something like this:
$orders = Order::with(array('shop' => function($query)
{
$query->where('location', '=', 'japan');
}))->get();
Which should give you all orders for a shop located in japan.
More informations about this type of request:
http://laravel.com/docs/eloquent#eager-loading
in CostumerModel you need set a relationship (One To Many):
public function order()
{
return $this->hasMany('OrderModel', 'foreign_key_in_orderTable');
}
in OrderModel too:
public function costumer()
{
return $this->belongsTo('CostumerModel', 'foreign_key_in_orderTable');
}
then in OrderModel one more relationship with Shop (One To One):
public function shop()
{
return $this->hasOne('ShopModel', 'foreign_key');
}
Now in ShopModel (One To One):
public function order()
{
return $this->belongsTo('OrderModel', 'local_key');
}
query:
$orders = Customer::with('costumer', 'shop')->where('location','=','Japan')->get();

Resources