I have two tables. Like this
**
user_accounts usersonglists
-------------- ---------------
id id
username user_account_id
slug etc..
etc..
**
I created a route like this
/u/{slug}/songlists
This relation method in songlist model
public function userAccounts()
{
return $this->belongsTo('App\Models\User\UserAccounts','user_account_id','id');
}
I created controller method like this
$songLists = $SongListRepository->getSongListsByUserSlug($slug);
This is getSongListByUserSlug($slug) method
$songList = $this->model->with('userAccounts')->get();
I want to get songlists by user with $slug.
Can someone help me?
You're looking for the whereHas method:
$query = $this->model->with('userAccounts');
$query->whereHas('userAccounts', function($query) use ($slug) {
$query->where('slug', $slug);
})
$lists = $query->get();
BTW, you should probably rename that userAccounts method to the singular userAccount.
An easier way might be to start from the account:
$lists = UserAccount::where('slug', $slug)->songLists;
Assuming you've set up the inverse relationship.
Related
I have a Spaces and an Interests table.
I am currently able to get a list of the Space Id's saved as $spaceList but I want my $query variable to retrieve a list of interests that the space_id foreign key matches one of the space_id's from my $spaceList variable.
public function index() {
$user_id = auth()->user()->id;
$user = User::find($user_id);
$spaceList = Space::where('user_id', $user_id)->pluck('space_id')->toArray();
$query = Interest::where('space_id', $spaceList);
$interests = $query->get();
return view('dashboard')->with('space', $user->space)->with('interest', $interests);
}
Thanks, I've been at this for ages now.
you should use whereIn instead of where
$spaceList = Space::where('user_id', $user_id)->pluck('space_id')->toArray();
$query = Interest::whereIn('space_id', $spaceList);
In Laravel Eloquent, this is what the Querying Relationship Existence working on
You won't need the $spaceList variable here if it's not used in other places
$query = Interest::whereHas('spaces', function($query) use ($user_id) {
$query->where('user_id', '=', $user_id);
});
Please notice, to get this work, you'll need to declare the spaces one-to-many relation in the Interest Module
Should be something like this, more details see document here
namespace App;
use Illuminate\Database\Eloquent\Model;
class Interest extends Model
{
public function spaces()
{
// space_id is the column name in your space database table
// id the the foreign-key target, generally is the primary-key of space table
return $this->hasMany('App\Space', 'space_id', 'id');
}
}
I have three tables:
Brand
-----------------
id | name | wheel
-----------------
Wheel
-----------------------------
id |no_of_wheel | brand_wheel
-----------------------------
Brand_Wheel
------------------------
id | brand_id | wheel_id
------------------------
I have the following models defined:
class brand
{
public function brandWheel(){
return $this->hasMany(BrandWheel::class);
}
}
class BrandWheel
{
public function brand(){
return $this->belongsTo(Brand::class);
}
}
I want to get those brands whose wheel_id is 2.
I tired:
$brands = Brand::with(['brandWheel' => function($query){
$query->where('wheel_id','=',2);
}])->get();
This code gives me all the brands I have in the table. Is there something I am missing?
You should use the whereHas statement. The with method will eager load the given relationships. You can find more documentation here.
$brands = Brand::with('brandWheel')->whereHas('brandWheel', function($query) {
$query->where('wheel_id', 2);
})->get();
In case you only want Brands that has a brandWheel relationship use has. Checkout documentation for more about this.
Your code get all brands and append to them only brandWheels where wheel_id = 2. You need to use whereHas() method.
$brands = Brand::with('brandWheel')
->whereHas('brandWheel', function($query){
$query->where('wheel_id', 2)
})
->get();
You need to use the Many to Many eloquent relationship described here https://laravel.com/docs/5.7/eloquent-relationships#many-to-many
So your models should look like:
class Brand
{
public function brandWheels()
{
return $this->belongsToMany(BrandWheel::class);
}
}
class BrandWheel
{
public function brands()
{
return $this->belongsToMany(Brand::class);
}
}
Notice how I have capitalized your model names since this is the naming convention as defined here https://www.php-fig.org/psr/psr-1/#3-namespace-and-class-names.
I've also made your relationship names plural, since they are many-to-many, they could return multiple results.
You can now do your query doing something along this line (not tested, might not be 100% accurate):
$brands = BrandWheel::find(2)->brands();
I have many to many connect with between user - cityarea.
I have also area which connect cityarea (One cityarea can connect only one area).
I have this database structure:
users
id
username
password
cityareas
id
name
area_id
cityarea_user
id
cityarea_id
user_id
areas
id
name
Next I have Models
User
public function cityareas()
{
return $this->belongsToMany('App\Cityarea');
}
Cityarea
public function area()
{
return $this->belongsTo('App\Area');
}
public function users()
{
return $this->belongsToMany('\App\User');
}
Area
public function cityareas()
{
return $this->hasMany('App\Cityarea');
}
QUESTION:
How I can get all users where areas.name = "South" with Eloquent ?
Thanks!!
By using whereHas, you can do:
$users = User::whereHas('cityareas.area', function ($query) {
$query->where('name', 'South');
})->get();
Jeune Guerrier solution is perfect, but you can use with() method of eloquent If you also need cityarea collection along with users collection.
$users = User::with('cityareas')->whereHas('cityareas.area', function ($query) {
$query->where('name', 'South');
})->get();
This is exactly what the belongs to many relationships is built for.
You simply have to do, Cityarea::where('name', 'South')->first()->users;
If you want to do something further with the query, e.g. sort by users created at, you can do
Cityarea::where('name', 'South')->first()->users()->orderBy('creaated_at', desc')->get();
Note that if there is no such Cityarea with name 'South', the ->first() query above will return null and therefore will fail to fetch the users.
A more performant way to do it programmatically is to use the whereHas approach as discussed in the comments below.
Hello I'm very new in Laravel and, I'm having the following models :
organizations
-----------------
id
name
public function users()
{
return $this->belongsToMany( 'App\User' );
}
users
-----------------
id
name
organization_user
------------------
user_id
organization_id
The there is a many to many relationship between organization and user. Now I want to find the organization where the user belongs to. How can I add a where condition for the user in the relationship.
For example I want to find all the organization of the logged in user. I'm trying the following :
$organisations = Organisation::where('user_id' , '=' , $user->id)->paginate(10);
But its not working because user_id is in my Pivot Table. Please help and Thanks in advance.
I think you need to use wherePivot() function in your code like
$organisations = Organisation::with(array('user'=> function($query) use ($user){
$query->wherePivot('user_id' , '=' , $user->id);
}) )->paginate(10);
May be this can help
I think below code may help you
$organisations = Illuminate\Support\Facades\DB::table('organizations')
->join('organization_user', 'organizations.id', '=', 'organization_user.organization_id')
->join('users', 'users.id', '=', 'organization_user.user_id')
->where('users.id', '=', $user->id)
->paginate(10);
I think you need to add this to your User Model
public function organizations()
{
return $this->belongsToMany('App\Organization');
}
and then will be something simple like this
$organizations = Auth()->user()->organizations;
First of all add your relations in your models:
User.php
public function organizations()
{
return $this->hasMany(organization_user::class);
}
Or
public function organizations()
{
return $this->hasManyThrough(organizations::class,organization_user::class);
}
I recommend the second one. For more information follow this:
Laravel hasManyThrough
Please note that use same idea for organization model to create the relation
I have 4 tables:
projects: id, text
comments: id, text
comment_project: project_id, comment_id
project_group: project_id, user_id
My goal is to take all commets and user details for some project.
Currently I am able to get all comments for projects like this:
class Project extends Model {
public function comments(){
return $this->belongsToMany('App\Comment','comment_project');
}
}
and in controller I do like this:
$comments = Project::find(1)->comments()->get();
return $comments;
Any idea how to take only comments and user details for selected project if project_id and user_id exists in project_group table?
You'll need to set another relation method for project_group in your Model, then you should be able to get this like so:
$comments = Project::with(['comments','project_group'])
->whereHas('project_group',function($q){
$q->whereNotNull('user_id');
$q->whereNotNull('project_id');
});
dd($comments);
Model:
class Project extends Model {
public function comments(){
return $this->hasMany('App\Comment','comment_project');
}
public function project_group(){
return $this->hasMany('App\project_group','comment_project'); // < make sure this is the name of your model!
}
}
Try this:
$comments = Project::whereHas('groups',function($q){
$q->where('project_id',1);
})->whereHas('comments', function($q){
$q->where('user_id',Auth::id())->where('project_id',1);
})
->get();
return $comments;
Here is how I do this, if anyone has better idea pls comment...
Both methods are belongToMany()
$userCondition = function($q){
$q->where('user_id',Auth::id())->where('project_id',1);
};
$commentsCondition = function($q){
$q->where('project_id',1);
};
$comments = Project::with(['comments' => $commentsCondition,'groups' => $userCondition])
->whereHas('groups', $userCondition)
->whereHas('comments', $commentsCondition)
->get();
return $comments;