How to query a model and its related model in laravel - laravel-5

I am building a Laravel 5.5 project where i have 2 related models, User and Service with a relationship like so:
Inside User.php
public function service()
{
return $this->hasMany('App\Service');
}
and inside Service.php
public function user()
{
return $this->belongsTo('App\User');
}
I need to query the service model for a service column where the query is either service_name or the name of a user. In effect, the query will search for the item in the service model and the related user model.
I have written the query below but its returning an empty collection:
$items = Service::where('service_name', 'LIKE', "%".$query."%")
->whereHas('user', function($q) use ($query){
$q->where('name', 'LIKE', "%".$query."%");))->get();
What am i doing wrong?
NB: My search on google, stackoverflow and laravel documentation didn't give exactly what i need hence my question please.

Change your "whereHas()" to "OrWhereHas()".

Related

API give result as per usertype

Usertypes table
User Table
I want to create api which give data particular user_type_id.. when i click api/usertype/1 than show only player list of user
Your API route should be:
Route::get('/api/usertype/{id}', 'HomeController#getUsertype');
Your API controller:
use DB;
/** You have pass user_type_id **/
public function getUsertype($id){
$user = DB::table('users')
->where('user_type_id', $id)
->select('users.*')
->get();
dd($user);
}

Laravel- Eloquent many to many get unattached data

I have User, Shop and Product model on my app. And relationship like this:
User
public function products(){
return $this->hasMany("App\Product");
}
public function shops(){
return $this->hasMany("App\Shop");
}
Shop
public function user(){
return $this->belongsTo("App\User");
}
public function products(){
return $this->belongsToMany("App\Product");
}
Product
public function user(){
return $this->belongsTo('App\User');
}
public function shops(){
return $this->belongsToMany("App\Shop");
}
So, user can add Products and Shops and then attach a product to many shop. Now I can get all of the attached shops by $product->shops on product page and auth users all shop by auth()->user()->shops. Actually, I want to show the auth users shop that is not attached to this Product on the Product page. According to Laravel documentation, I write some code but for some reason it doesn't work. My code is :
auth()->user()->shops()->whereDoesntHave('products', function (Builder $query) {
$query->where('id','!=', $product->id);
})->get();
Error:
Any help will be appreciated.
Thanks
Converting comment to an answer here.
Firstly, the usage of function(Builder $query) is targeting the incorrect version of Builder (likely a namespacing issue), so simply removing Builder from the function should allow it to resolve.
Secondly, to use $product in scope of the new function, it needs to be passed use use($product), otherwise you'll get an Undefined variable $product error.
Altogether, the new function should look like this:
auth()->user()->shops()->whereDoesntHave('products', function ($query) use($product) {
$query->where('id','!=', $product->id);
})->get();

How to retrieve all related models in a many to many relationship Laravel?

I am trying to retrieve all related models with another model through an intermediary table but can't figure out how. The Laravel docs say you can do something like this:
$roles = App\User::find(1)->roles()->orderBy('name')->get();
But when I try to apply that to my code
$roles = User::where('id', $user->id)->roles()->get();
It does not work. I am accepting the user model through my controller, so I do have access to it.
The relationship is also defined like so:
User
public function roles()
{
return $this->belongsToMany(Role::class);
}
Role
public function users()
{
return $this->belongsToMany(User::class);
}
How can I get all of the roles associated with a particular user?
edit/update:
I know I can simply use a foreach loop and get all of the roles associated with a particular user, but I am trying to return a resource collection, so I cannot do it that way
Try this,
I am assuming that $user_id is the parameter which is passed into the controller from the URL,
$roles=User::findOrFail($user_id)->roles;
But before running the above code, I assume that you have created the pivot table for many to many relationship with columns user_id and role_id. And have named the pivot table as role_user.
Hope this works
the problem with your second approach is calling roles() function on an 'Eloquent Query Builder' instance. You need to make sure to call roles() function on a 'User Model'.
this part of code User::where('id', $user->id) doesn't return a 'User Model'.
To get an 'User Model' from a 'Query Builder' instance you need to call first() function.
possible solution.
$roles = User::where('id', $user->id)->first()->roles;
The reason why you're getting the errors, is because before calling the method first() (or find() or findOrFail()), the instance is a QueryBuilder. and the roles() method exist only on an User::class instance.
if you are trying to get the user with an attribute roles containing a collection (array) of all his roles do:
$user = User::where('id', $user->id)->with('roles')->first();
if you need just the array of roles, you have two choices;
either get the user and then get his roles:
$user = App\User::find($userId);
$roles = $user->roles()->orderBy('name')->get();
//the same as
$roles = App\User::find($userId)->roles()->orderBy('name')->get();
or get the Roles (only one query)
$roles = Role::whereHas('users', function($users) use($userId) {
$users->where('id','=',$userId);
})->get();
Hope this gives you enough insight to build the exact code you need.
User
use App\User;
public function roles()
{
return $this->belongsToMany('App\Users', 'user_id');
}
Role
use App\Roles;
public function users()
{
return $this->belongsToMany('App\Roles');
}
Controller
$roles = User::where('id', $user->id)->roles()->get();
Try this one. I think your relationship is not correct.
You can read more information here Many To Many
You can use the following solution to retrieve all related models in a many to many relationship in Laravel:
$roles = User::where('id', $user->id)->get();
foreach($roles as $rol){
$rol->roles;
}

Laravel - How to get data from a table related with pivot table

I have this model for notifications table:
class Notification extends Model
{
public function users()
{
return $this->belongsToMany(User::class, 'notification_user', 'notification_id', 'user_id');
}
}
And this method in controller for getting data from notifications where id of notifications is related to a pivot table named notification_user:
$myNotifications = DB::table('notification_user')
->join('notifications', 'notifications.id', 'notification_user.notification_id')
->where('notification_user.user_id', $userId)
->where('notification_user.seen', 0)
->get();
the result of $myNotifications is correct but I want to use Model and its relationship instead of DB.
How can I get all records in notifications where each notification related to a specific user which is not seen by the user.
You need to add ->withPivot('seen') to the relationship:
public function users()
{
return $this
->belongsToMany(User::class, 'notification_user', 'notification_id', 'user_id')
->withPivot('seen');
}
Then you can do:
Notification::whereHas('users', function ($q) use ($userId) {
$q->where('id', $userId)->where('seen', 0);
})->get();
To avoid joining users, your other option is whereExists:
Notification::whereExists(function ($q) use ($userId) {
$q
->selectRaw(1)
->table('notification_user')
->whereRaw('notifications.id = notification_user.notification_id')
->where('user_id', $userId)
->where('seen', 0);
})->get();
Should still be more performant, but not much more elegant.
You will have to define the same relation in User model as notifications and then:
$notifications = User::where('id', $user_id)->notifications()->where('seen', 0)->get();
You can use with keyword for eager loading inside your controller.
like if you have any relation defined inside your model, just add a with('modelRelation') before your get() statement in eloquent.
Happy Coding.

Laravel: Find all posts made by a user using name field

I want to fetch all posts made by a user by matching the name of the user from the route url using Eloquent
My User.php has relationship as follows
public function posts() {
return $this->hasMany('App\Post');
}
My Post.php model has following relationship:
public function user() {
return $this->belongsTo('App\User');
}
my route is like following:
Route::get('/users/{name}', 'UsersController#show');
I know if I want to fetch all posts by a user I need to do something like this
public function show($name) {
$user = User::find(1);
$posts = $users->posts()->get();
return view('users.show', compact('posts'));
}
but I want to find the user based on the name field in the database and not the id
I cant use ->posts() if I use where like Users::where('name', $name)->posts()->get(); , It throws error.
How do I fetch all posts of a user by matching his name in database with eloquent
You can use whereHas():
$posts = Post::whereHas('user', function($q) use($name) {
$q->where('name', $name);
})->get();
Or you can do this:
User::where('name', $name)->first()->posts()->get();
Or:
$user = User::where('name', $name)->first();
$posts = Post::where('user_id', $user->id)->get();
All these options will create two queries.

Resources