Laravel 5: DB::table() and relationship in Eloquent - php

I have a hasMany relationship between Community and LangCommunity and I am trying to sort by name field without losing the relationship in the view.
Model Community
protected $fillable = ['province_id', 'active', 'address', 'phone', 'google_map'];
public function langs()
{
return $this->hasMany('App\Models\LangCommunity');
}
Model LangCommunity
protected $fillable = ['community_id', 'lang_id', 'name', 'text'];
public function community()
{
return $this->belongsTo('App\Models\Community');
}
In controller, I have:
$data['communities'] = DB::table('communities')
->join('lang_communities', 'communities.id', '=', 'lang_communities.community_id')
->select('communities.*', 'lang_communities.name')
->where('lang_communities.lang_id', '1')
->orderBy('lang_communities.name', 'asc')
->paginate($num);
This work, but I can't use the relationship in the view. I have tried to do it in the following way:
$data['communities'] = Community::with(['langs' => function($query)
{
$query
->where('lang_id', '1')
->join('communities', 'communities.id', '=', 'lang_communities.community_id')
->orderBy('lang_communities.name', 'asc');
}])->paginate($num);
But this does not sort by name. Any idea?

Ok. I have managed to solve it ;)
$data['communities'] = Community::join('lang_communities', 'communities.id', '=', 'lang_communities.community_id')
->select('communities.*', 'lang_communities.name')
->where('lang_communities.lang_id', '1')
->orderBy('lang_communities.name', 'asc')
->paginate($num);

Did you try :
$data['communities'] = Community::with(['langs' => function ($q) {
$q->orderBy('name', 'asc');
}])
->whereHas('langs', function ($query) {
$query->where('lang_id', 1);
})->get();

Related

Laravel Relationship with condtion on foreign key (toggle foreign key on relation)

For a small chat purpose, I am using below relationship
Model
class Chat extends Model
{
protected $table = 'chats';
protected $primaryKey = 'chat_id';
protected $filllable = [
'chat_id',
'sender_id',
'reciever_id',
'content',
'sender_type',
'reciever_type',
'view_status'
];
class Admin extends Authenticatable
{
public function chats()
{
return $this->hasMany(Chat::class, 'sender_id', 'admin_id');
}
}
but the issue is both user's are in the same table some times it is sender_id sometimes it is reciever_id so I want to return the above relationship with the condition (if the receiver type in chat table is 1 it should be reciever_id else it should be the sender_id)
Controller
$seller_id = auth()->guard('seller')->user()->seller_id;
$chatLists = Admin::whereHas('chats', function ($q) {
$q->where('reciever_type', 2);
$q->orWhere('sender_type', 2);
})
->with(['chats' => function ($q) {
$q->where('reciever_type', 2);
$q->orWhere('sender_type', 2);
}])
->orderBy('created_at', 'desc')
->get();
return view('seller.chat.index', compact('chatLists'));
}
sender_type and receiver_type don't seem to do much.
If you retrieve $seller_id and intend to get all chats from $seller_id,
both chats with $seller_id as sender
and chats with $seller_id as receiver
Then your query could look like this.
$seller_id = auth()->guard('seller')->user()->seller_id;
$chatLists = Admin::whereHas('chats', function ($q) use ($seller_id) {
$q->where('receiver_id', $seller_id)
->orWhere('sender_id', $seller_id);
})
->with(['chats' => function ($q) use ($seller_id) {
$q->where('receiver_id', $seller_id)
->orWhere('sender_id', $seller_id);
}])
->latest()
->get();

Eloquent ORM order by deep relation

Models:
Category (id, name)
Item (id, name, category_id, ...)
OrderList (id, user_id, ...)
OrderListItem(id, item_id, order_list_id, user_sort_order, ...)
I want OrderListItems of each OrderList to be sorted:
By user_sort_order
Or by Category name
What I do:
$grouped = $request->input('grouped', false) === "true";
$user = User::findOrFail($id);
$order_lists = OrderList::where('kitchen_id', $user->id)
->with(['order_list_items' => function ($q) use ($grouped) {
$q->when($grouped, function ($q) {
return $q->with(['item' => function ($q) {
return $q->with(['category' => function ($q) {
return $q->orderBy('name', 'asc');
}]);
}]);
}, function ($q) {
return $q->orderBy('kitchen_sort_order', 'asc');
})->with('supplier')
->with(['item' => function ($q) {
return $q->with('category');
}]);
}])->get();
Ordering by category name isn't working. I had been searching for hours but found no answer. Is it possible to do something like this in Eloquent ORM? Btw, Django is able to do it in a really nice way.
You can use a HasManyThrough relationship as a BelongsToThrough and combine it with a modified withCount().Not the most elegant solution, but it works:
class OrderListItem extends Model {
public function category() {
return $this->hasManyThrough(Category::class, Item::class,
'id', 'id', 'item_id', 'category_id');
}
}
$order_lists = OrderList::where('kitchen_id', $user->id)
->with(['order_list_items' => function ($q) use ($grouped) {
$q->when($grouped, function ($q) {
return $q->withCount(['category as category_name' => function ($q) {
$q->select('categories.name');
}])->orderBy('category_name');
}, function ($q) {
return $q->orderBy('kitchen_sort_order', 'asc');
})->with('supplier')
->with(['item' => function ($q) {
return $q->with('category');
}]);
}])->get();

How can I get data when I search using relationship eloquent laravel

How to get value relationships in eloquent laravel
here is my model Food
class food extends Model
{
protected $table = 'food';
protected $fillable = [
'name'
];
public function foodType()
{
return $this->belongsTo(Food_type::class, 'food_type_id');
}
}
here is my food_type model
class food_type extends Model
{
protected $table = 'food_type';
protected $fillable = [
'name', 'description'
];
public function getFood()
{
return $this->hasMany(Food::class);
}
}
I want to get food_type.name in food_type table .How can I query like this
$search = $request->search
$food = Food::with(['foodType'])
->where('name', 'like', '%'.$search.'%')
->orWhere('foodType.name', 'like', '%'.$search.'%')->get();
Relationships are not included with joins when you use eager loading. Review the documentation as it covers how to use whereHas and other relationship related methods.
$food = Food::with(['foodType'])
->where('name', 'like', '%'.$search.'%')
->orWhereHas('foodType' function($q) {
$q->where('name', 'like', '%'.$search.'%');
})
->get();

How to write this query in Laravel 5.2?

I am using Laravel 5.2 ,how to write this query?
There are two tables,user and articles,they have a one-to-many relationship.
I want to query users according to these conditions:
1、Show users who have articles,not show users who have not articles.
2、Articles contain two types,published and not published, "1" indicates published,show published articles ,not show articles which not published.
3、30 users are shown per page.
Like this, it's not right ,how to modify it?
HomeController:
public function index()
{
$users = User::with('articles')->where('is_published','=',1)->paginate(30);
return view('index', compact('users'));
}
User:
class User extends Model implements AuthenticatableContract, CanResetPasswordContract, HasRoleAndPermissionContract
{
use Authenticatable, CanResetPassword, HasRoleAndPermission;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function articles()
{
return $this->hasMany(Article::class);
}
}
Article:
class Article extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
//edit-1:
//Scope a query to only include status=1.
public function scopeStatus($query)
{
return $query->where('status',1);
}
}
edit:
#SSuhat #RamilAmr Thanks! If there is a Local Scope in Model "Article",how to modify the answer:
$query = User::with(['articles' => function ($q) {
$q->where('is_published', 1);
}])
->has('articles') //<<<<<<<<<
->paginate(30);
return $query;
Try this:
$query = User::with(['articles' => function ($q) {
$q->where('is_published', 1);
}])->paginate(30);
return $query;
if the user has not any articles,the user will not be shown,how to filter?
Try this code:
$query = User::with(['articles' => function ($q) {
$q->where('is_published', 1);
}])
->has('articles') //<<<<<<<<<
->paginate(30);
return $query;
$query = User::with('articles')->wherehas('articles', function ($q) {
$q->where('is_published', 1);
})->paginate(30);
return $query;
I hope this helps you.

Using 'with' in many-to-many relationship in Laravel

I have a table user - User(Model), which has relationship:
public function roles()
{
return $this->belongsToMany(Config::get('entrust.role'), Config::get('entrust.role_user_table'), 'user_id', 'role_id');
}
public function regions() {
return $this->belongsToMany('App\Regions', 'user_region', 'user_id', 'region_id');
}
I am trying this query, but it doesn't me the required result
$result = User::with(['roles' => function($query) {
$query->select('user_id','role_id');
},
'regions' => function($query) {
$query->select('user_id','region_id', 'region_name');
}])
->where('user_id', '=', $id)
->get()->toArray();
It only gives me data from user table and doesn't give the relationship data.
What am I missing out??
The notation you are using should be used for constraints. From your code it seems you don't actually need any contraints.
$result = User::with(['roles', 'regions'])
->where('user_id', '=', $id)
->first()->toArray();
The relationship you defined is only a belongsTo. You should probably use a hasMany relationship.
If you're using 5.1 try this:
$result = User::whereHas(['roles' => function($query) {
$query->lists('user_id','role_id');
},
'regions' => function($query) {
$query->lists('user_id','region_id','region_name');
}])
->where('user_id', '=', $id)
->all();
if not remove all() and use get()
This worked for me.
$users = User::with('regions', 'roles')->get();
$userInfo = [];
foreach ($users as $user)
{
$userInfo[] = [
'users' => $user,
'regions' => $user->regions->toArray(),
'roles' => $user->roles->toArray(),
];
}

Categories